fancydialogs: Refactor dialog data, storage and dialog showing

This commit is contained in:
Oliver
2025-06-15 19:01:29 +02:00
committed by Oliver
parent 627f50467c
commit 603ddd2151
31 changed files with 151 additions and 327 deletions

View File

@@ -1,20 +1,16 @@
package com.fancyinnovations.fancydialogs.api;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.types.DialogType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public abstract class Dialog {
private String id;
private Type type;
private DialogType dialog;
protected String id;
protected DialogData data;
public Dialog(@NotNull String id, @NotNull Type type, @NotNull DialogType dialog) {
public Dialog(String id, DialogData data) {
this.id = id;
this.type = type;
this.dialog = dialog;
this.data = data;
}
public Dialog() {
@@ -24,27 +20,11 @@ public abstract class Dialog {
abstract public void close(Player player);
public @NotNull String getId() {
public String getId() {
return id;
}
public @NotNull Type getType() {
return type;
}
public void setType(@NotNull Type type) {
this.type = type;
}
public @NotNull DialogType getDialog() {
return dialog;
}
public void setDialog(@NotNull DialogType dialog) {
this.dialog = dialog;
}
public enum Type {
NOTICE,
public DialogData getData() {
return data;
}
}

View File

@@ -1,17 +1,4 @@
package com.fancyinnovations.fancydialogs.api.data;
public enum DialogAction {
CLOSE(0, "close"),
NONE(1, "none"),
WAIT_FOR_RESPONSE(2, "wait_for_response");
private final int id;
private final String name;
DialogAction(final int id, final String name) {
this.id = id;
this.name = name;
}
public abstract class DialogAction {
}

View File

@@ -0,0 +1,6 @@
package com.fancyinnovations.fancydialogs.api.data;
public record DialogBodyData(
String text
) {
}

View File

@@ -0,0 +1,8 @@
package com.fancyinnovations.fancydialogs.api.data;
public record DialogButton(
String label,
String tooltip,
String action
) {
}

View File

@@ -1,20 +1,17 @@
package com.fancyinnovations.fancydialogs.api.data;
import com.fancyinnovations.fancydialogs.api.data.body.DialogBody;
import com.fancyinnovations.fancydialogs.api.data.input.DialogInput;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public record DialogData(
@NotNull String id,
@NotNull String title,
@Nullable String externalTitle,
boolean canCloseWithEscape,
boolean pause, // only relevant in single player
@NotNull DialogAction afterAction,
@NotNull List<DialogBody> body,
@NotNull List<DialogInput> inputs
@NotNull List<DialogBodyData> body,
@NotNull List<DialogButton> buttons
) {
}

View File

@@ -1,4 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.body;
public interface DialogBody {
}

View File

@@ -1,16 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.body;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record ItemBody(
@NotNull ItemStack item,
@Nullable TextBody description,
boolean showDecorations,
boolean showTooltip,
int width,
int height
) implements DialogBody {
}

View File

@@ -1,10 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.body;
import org.jetbrains.annotations.NotNull;
public record TextBody(
@NotNull String content,
int width
) implements DialogBody {
}

View File

@@ -1,11 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.click;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record Button(
@NotNull String label,
@Nullable String tooltip,
int width
) {
}

View File

@@ -1,10 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.click;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record ClickAction(
@NotNull Button button,
@Nullable ClickEvent onClick
) {
}

View File

@@ -1,12 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.click;
public enum ClickEvent {
OPEN_URL,
OPEN_FILE,
RUN_COMMAND,
SUGGEST_COMMAND,
SHOW_DIALOG,
CHANGE_PAGE,
COPY_TO_CLIPBOARD,
CUSTOM,
}

View File

@@ -1,12 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.input;
import org.jetbrains.annotations.NotNull;
public record CheckboxInput(
@NotNull String label,
boolean initial,
@NotNull String onTrue,
@NotNull String onFalse
) implements DialogInput {
}

View File

@@ -1,22 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.input;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public record ComboboxInput (
int width,
@NotNull List<Entry> entries,
@NotNull String label,
boolean labelVisible
) implements DialogInput {
public record Entry(
@NotNull String id,
@Nullable String display,
boolean initial
) {
}
}

View File

@@ -1,4 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.input;
public interface DialogInput {
}

View File

@@ -1,22 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.input;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record SliderInput(
int width,
@NotNull String label,
@NotNull String labelFormat,
@NotNull RangeInfo rangeInfo
) implements DialogInput {
public record RangeInfo(
double start,
double end,
@Nullable Double initial,
int steps
) {
}
}

View File

@@ -1,13 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.input;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record TextInput(
int width,
@NotNull String label,
boolean labelVisible,
@Nullable String initial
) implements DialogInput {
}

View File

@@ -1,4 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.submit;
public interface SubmitMethod {
}

View File

@@ -1,13 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.click.ClickAction;
import org.jetbrains.annotations.NotNull;
public record ConfirmationDialog(
@NotNull DialogData common,
@NotNull ClickAction yesButton,
@NotNull ClickAction noButton
) implements DialogType {
}

View File

@@ -1,17 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.click.ClickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public record DialogListDialog(
@NotNull DialogData common,
@NotNull List<DialogType> dialogs,
@Nullable ClickEvent exitAction,
int columns,
int buttonWidth
) implements DialogType {
}

View File

@@ -1,4 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
public interface DialogType {
}

View File

@@ -1,22 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.click.Button;
import com.fancyinnovations.fancydialogs.api.data.input.DialogInput;
import com.fancyinnovations.fancydialogs.api.data.submit.SubmitMethod;
import org.jetbrains.annotations.NotNull;
public interface InputFormDialog extends DialogType {
record Input(
@NotNull String key,
@NotNull DialogInput control
) {
}
record SubmitAction(
@NotNull String id,
@NotNull Button buttonData,
@NotNull SubmitMethod method
) {
}
}

View File

@@ -1,18 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.click.ClickAction;
import com.fancyinnovations.fancydialogs.api.data.click.ClickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public record MultiActionDialog(
@NotNull DialogData common,
@NotNull List<ClickAction> actions,
@Nullable ClickEvent exitAction,
int columns
) implements DialogType {
}

View File

@@ -1,11 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.click.ClickAction;
import org.jetbrains.annotations.NotNull;
public record NoticeDialog(
@NotNull DialogData common,
@NotNull ClickAction button
) implements DialogType {
}

View File

@@ -1,14 +0,0 @@
package com.fancyinnovations.fancydialogs.api.data.types;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.api.data.click.ClickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record ServerLinksDialog(
@NotNull DialogData common,
@Nullable ClickEvent exitAction,
int columns,
int buttonWidth
) implements DialogType {
}

View File

@@ -1,9 +1,13 @@
package com.fancyinnovations.fancydialogs;
import com.fancyinnovations.fancydialogs.api.Dialog;
import com.fancyinnovations.fancydialogs.api.data.DialogBodyData;
import com.fancyinnovations.fancydialogs.api.data.DialogButton;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import com.fancyinnovations.fancydialogs.commands.TutorialCMD;
import com.fancyinnovations.fancydialogs.config.FDFeatureFlags;
import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig;
import com.fancyinnovations.fancydialogs.dialog.DialogImpl;
import com.fancyinnovations.fancydialogs.listener.PlayerJoinListener;
import com.fancyinnovations.fancydialogs.registry.DialogRegistry;
import com.fancyinnovations.fancydialogs.storage.DialogStorage;
@@ -86,7 +90,33 @@ public class FancyDialogsPlugin extends JavaPlugin {
translator.setSelectedLanguage(selectedLanguage);
dialogStorage = new JsonDialogStorage();
Collection<Dialog> dialogs = dialogStorage.loadAll();
Collection<DialogData> dialogData = dialogStorage.loadAll();
DialogData welcomeDialog = new DialogData(
"welcome_to_fancydialogs_dialog",
"Welcome to FancyDialogs",
"Welcome to FancyDialogs",
false,
List.of(
new DialogBodyData("Welcome to FancyDialogs! This is a sample dialog to get you started.")
),
List.of(
new DialogButton(
"Close",
"Close the dialog",
"close_dialog"
)
)
);
dialogStorage.save(welcomeDialog);
dialogData.add(welcomeDialog);
List<Dialog> dialogs = new ArrayList<>();
for (DialogData data : dialogData) {
Dialog dialog = new DialogImpl(data.id(), data);
dialogs.add(dialog);
fancyLogger.debug("Loaded dialog: %s".formatted(data.id()));
}
dialogRegistry = new DialogRegistry();
dialogs.forEach(dialogRegistry::register);
@@ -131,6 +161,10 @@ public class FancyDialogsPlugin extends JavaPlugin {
@Override
public void onDisable() {
for (Dialog dialog : dialogRegistry.getAll()) {
dialogStorage.save(dialog.getData());
}
fancyLogger.info("Successfully disabled FancyDialogs version %s".formatted(getDescription().getVersion()));
}

View File

@@ -23,7 +23,7 @@ public class FancyDialogsConfig {
logLevel = (String) ConfigHelper.getOrDefault(config, "log_level", "INFO");
config.setInlineComments("log_level", List.of("The log level of the plugin. Possible values: DEBUG, INFO, WARN, ERROR."));
welcomeDialogID = (String) ConfigHelper.getOrDefault(config, "welcome_dialog_id", "welcome-dialog");
welcomeDialogID = (String) ConfigHelper.getOrDefault(config, "welcome_dialog_id", "welcome_to_fancydialogs_dialog");
config.setInlineComments("welcome_dialog_id", List.of("The ID of the dialog which will be shown to the player when they join the server for the first time."));
quickActionsDialogID = (String) ConfigHelper.getOrDefault(config, "quick_actions_dialog_id", "quick-actions-dialog");

View File

@@ -1,24 +1,84 @@
package com.fancyinnovations.fancydialogs.dialog;
import com.fancyinnovations.fancydialogs.api.Dialog;
import com.fancyinnovations.fancydialogs.api.data.types.DialogType;
import com.fancyinnovations.fancydialogs.api.data.DialogBodyData;
import com.fancyinnovations.fancydialogs.api.data.DialogButton;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import de.oliver.fancysitula.api.dialogs.FS_CommonDialogData;
import de.oliver.fancysitula.api.dialogs.FS_DialogAction;
import de.oliver.fancysitula.api.dialogs.actions.FS_CommonButtonData;
import de.oliver.fancysitula.api.dialogs.actions.FS_DialogActionButton;
import de.oliver.fancysitula.api.dialogs.actions.FS_DialogCustomAction;
import de.oliver.fancysitula.api.dialogs.body.FS_DialogBody;
import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody;
import de.oliver.fancysitula.api.dialogs.types.FS_MultiActionDialog;
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
import de.oliver.fancysitula.factories.FancySitula;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class DialogImpl extends Dialog {
public DialogImpl(@NotNull String id, @NotNull Type type, @NotNull DialogType dialog) {
super(id, type, dialog);
private FS_MultiActionDialog fsDialog;
public DialogImpl(String id, DialogData data) {
super(id, data);
init();
}
private void init() {
List<FS_DialogBody> body = new ArrayList<>();
for (DialogBodyData bodyData : data.body()) {
FS_DialogTextBody fsDialogTextBody = new FS_DialogTextBody(
bodyData.text(),
200 // default text width
);
body.add(fsDialogTextBody);
}
List<FS_DialogActionButton> actions = new ArrayList<>();
for (DialogButton button : data.buttons()) {
FS_DialogActionButton fsDialogActionButton = new FS_DialogActionButton(
new FS_CommonButtonData(
button.label(),
button.tooltip(),
150 // default button width
),
new FS_DialogCustomAction("fancydialogs_dialog_action", button.action())
);
actions.add(fsDialogActionButton);
}
this.fsDialog = new FS_MultiActionDialog(
new FS_CommonDialogData(
data.title(),
data.externalTitle(),
data.canCloseWithEscape(),
false,
FS_DialogAction.CLOSE,
body,
new ArrayList<>() // inputs
),
actions, // actions
null,
2
);
}
@Override
public void open(Player player) {
// TODO open dialog packet
FancySitula.PACKET_FACTORY
.createShowDialogPacket(fsDialog)
.send(new FS_RealPlayer(player));
}
@Override
public void close(Player player) {
// TODO close dialog packet
FancySitula.PACKET_FACTORY
.createClearDialogPacket()
.send(new FS_RealPlayer(player));
}
}

View File

@@ -11,6 +11,10 @@ public class PlayerJoinListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
boolean isNewPlayer = !event.getPlayer().hasPlayedBefore();
if (FancyDialogsPlugin.get().getFancyDialogsConfig().getLogLevel().equalsIgnoreCase("debug")) {
isNewPlayer = true;
}
if (isNewPlayer) {
String welcomeDialogID = FancyDialogsPlugin.get().getFancyDialogsConfig().getWelcomeDialogID();
Dialog dialog = FancyDialogsPlugin.get().getDialogRegistry().get(welcomeDialogID);

View File

@@ -1,20 +1,17 @@
package com.fancyinnovations.fancydialogs.storage;
import com.fancyinnovations.fancydialogs.api.Dialog;
import com.fancyinnovations.fancydialogs.api.data.types.DialogType;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import java.util.Collection;
public interface DialogStorage {
void save(Dialog dialog);
void save(DialogData dialog);
void saveBatch(Collection<Dialog> dialogs);
void saveBatch(Collection<DialogData> dialogs);
void delete(Dialog dialog);
void delete(DialogData dialog);
Collection<Dialog> loadAll(Dialog.Type type);
Collection<Dialog> loadAll();
Collection<DialogData> loadAll();
}

View File

@@ -1,7 +1,7 @@
package com.fancyinnovations.fancydialogs.storage;
import com.fancyinnovations.fancydialogs.FancyDialogsPlugin;
import com.fancyinnovations.fancydialogs.api.Dialog;
import com.fancyinnovations.fancydialogs.api.data.DialogData;
import de.oliver.jdb.JDB;
import java.io.IOException;
@@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class JsonDialogStorage implements DialogStorage{
public class JsonDialogStorage implements DialogStorage {
private final JDB jdb;
@@ -18,49 +18,38 @@ public class JsonDialogStorage implements DialogStorage{
}
@Override
public void save(Dialog dialog) {
public void save(DialogData dialog) {
try {
jdb.set(dialog.getType().name().toLowerCase() + "/" + dialog.getId(), dialog);
jdb.set(dialog.id(), dialog);
} catch (IOException e) {
FancyDialogsPlugin.get().getFancyLogger().error("Failed to save dialog " + dialog.getId());
FancyDialogsPlugin.get().getFancyLogger().error("Failed to save dialog " + dialog.id());
FancyDialogsPlugin.get().getFancyLogger().error(e);
}
}
@Override
public void saveBatch(Collection<Dialog> dialogs) {
for (Dialog dialog : dialogs) {
public void saveBatch(Collection<DialogData> dialogs) {
for (DialogData dialog : dialogs) {
save(dialog);
}
}
@Override
public void delete(Dialog dialog) {
jdb.delete(dialog.getType().name().toLowerCase() + "/" + dialog.getId());
public void delete(DialogData dialog) {
jdb.delete(dialog.id());
}
@Override
public Collection<Dialog> loadAll(Dialog.Type type) {
List<Dialog> dialogs = new ArrayList<>();
public Collection<DialogData> loadAll() {
List<DialogData> dialogs = new ArrayList<>();
try {
dialogs = jdb.getAll(type.name().toLowerCase(), Dialog.class);
dialogs = jdb.getAll("", DialogData.class);
} catch (IOException e) {
FancyDialogsPlugin.get().getFancyLogger().error("Failed to load all dialogs for type: " + type);
FancyDialogsPlugin.get().getFancyLogger().error("Failed to load all dialogs");
FancyDialogsPlugin.get().getFancyLogger().error(e);
}
return dialogs;
}
@Override
public Collection<Dialog> loadAll() {
List<Dialog> dialogs = new ArrayList<>();
for (Dialog.Type t : Dialog.Type.values()) {
dialogs.addAll(loadAll(t));
}
return dialogs;
}
}

View File

@@ -1,2 +1,3 @@
language_name: default
messages:
foo: "Foo"