1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-28 03:09:08 +00:00

Small refactor

This commit is contained in:
Eclipse
2025-06-05 12:34:45 +00:00
parent a71eb5e086
commit 40a922f3b5
6 changed files with 55 additions and 51 deletions

View File

@@ -112,19 +112,19 @@ public abstract class Dialog {
protected abstract Optional<DialogButton> onCancel();
protected FormBuilder<? extends FormBuilder<?,?,?>, ? extends Form, ? extends FormResponse> createForm(GeyserSession session, Optional<ParsedInputs> restored, DialogHolder holder) {
protected FormBuilder<? extends FormBuilder<?,?,?>, ? extends Form, ? extends FormResponse> createForm(DialogHolder holder, Optional<ParsedInputs> restored) {
if (inputs.isEmpty()) {
SimpleForm.Builder builder = SimpleForm.builder()
.translator(MinecraftLocale::getLocaleString, session.locale())
.translator(MinecraftLocale::getLocaleString, holder.session().locale())
.title(title);
builder.content(String.join("\n\n", labels));
builder.closedOrInvalidResultHandler(() -> holder.closeDialog(onCancel()));
addCustomComponents(session, builder, holder);
addCustomComponents(holder, builder);
return builder;
} else {
CustomForm.Builder builder = CustomForm.builder()
.translator(MinecraftLocale::getLocaleString, session.locale())
.translator(MinecraftLocale::getLocaleString, holder.session().locale())
.title(title);
for (String label : labels) {
builder.label(label);
@@ -132,27 +132,27 @@ public abstract class Dialog {
restored.ifPresentOrElse(last -> last.restore(builder), () -> inputs.forEach(input -> input.addComponent(builder)));
builder.closedOrInvalidResultHandler(response -> holder.closeDialog(onCancel()));
addCustomComponents(session, builder, holder);
addCustomComponents(holder, builder);
return builder;
}
}
protected abstract void addCustomComponents(GeyserSession session, CustomForm.Builder builder, DialogHolder holder);
protected abstract void addCustomComponents(DialogHolder holder, CustomForm.Builder builder);
protected abstract void addCustomComponents(GeyserSession session, SimpleForm.Builder builder, DialogHolder holder);
protected abstract void addCustomComponents(DialogHolder holder, SimpleForm.Builder builder);
public void sendForm(GeyserSession session, DialogHolder holder) {
session.sendDialogForm(createForm(session, Optional.empty(), holder).build());
public void sendForm(DialogHolder holder) {
holder.session().sendDialogForm(createForm(holder, Optional.empty()).build());
}
public void restoreForm(GeyserSession session, @NonNull ParsedInputs inputs, DialogHolder holder) {
session.sendDialogForm(createForm(session, Optional.of(inputs), holder).build());
public void restoreForm(DialogHolder holder, @NonNull ParsedInputs inputs) {
holder.session().sendDialogForm(createForm(holder, Optional.of(inputs)).build());
}
protected Optional<ParsedInputs> parseInput(GeyserSession session, CustomFormResponse response, DialogHolder holder) {
protected Optional<ParsedInputs> parseInput(DialogHolder holder, CustomFormResponse response) {
ParsedInputs parsed = new ParsedInputs(inputs, response);
if (parsed.hasErrors()) {
restoreForm(session, parsed, holder);
restoreForm(holder, parsed);
return Optional.empty();
}
return Optional.of(parsed);
@@ -176,10 +176,10 @@ public abstract class Dialog {
return new Dialog(session, map) {
@Override
protected void addCustomComponents(GeyserSession session, CustomForm.Builder builder, DialogHolder holder) {}
protected void addCustomComponents(DialogHolder holder, CustomForm.Builder builder) {}
@Override
protected void addCustomComponents(GeyserSession session, SimpleForm.Builder builder, DialogHolder holder) {}
protected void addCustomComponents(DialogHolder holder, SimpleForm.Builder builder) {}
@Override
protected Optional<DialogButton> onCancel() {

View File

@@ -25,11 +25,14 @@
package org.geysermc.geyser.session.dialog;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.cumulus.form.ModalForm;
import org.geysermc.cumulus.form.SimpleForm;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.dialog.action.DialogAction;
import org.geysermc.geyser.session.dialog.input.ParsedInputs;
import org.geysermc.geyser.text.MinecraftLocale;
@@ -82,7 +85,10 @@ import java.util.Optional;
*
* <p>Final note: when reading through this code, a dialog is "valid" when it is still considered open.</p>
*/
@Accessors(fluent = true)
public class DialogHolder {
@Getter
private final GeyserSession session;
private final DialogManager manager;
private final Dialog dialog;
@@ -100,7 +106,8 @@ public class DialogHolder {
private boolean shouldClose = false;
private ParsedInputs lastInputs;
public DialogHolder(DialogManager manager, Dialog dialog) {
public DialogHolder(GeyserSession session, DialogManager manager, Dialog dialog) {
this.session = session;
this.manager = manager;
this.dialog = dialog;
}
@@ -125,7 +132,7 @@ public class DialogHolder {
// Replace wait form with one with a back button if no replacement dialog was given
if (responseWaitTime > 0 && !sendBackButton && System.currentTimeMillis() - responseWaitTime > 5000) {
sendBackButton = true;
manager.session().closeForm(); // Automatically reopens with a back button
session.closeForm(); // Automatically reopens with a back button
}
}
@@ -170,9 +177,9 @@ public class DialogHolder {
// lastInputs might be null here since it's possible none were sent yet
// Bedrock doesn't send them when just closing the form
if (lastInputs == null) {
dialog.sendForm(manager.session(), this);
dialog.sendForm(this);
} else {
dialog.restoreForm(manager.session(), lastInputs, this);
dialog.restoreForm(this, lastInputs);
}
}
}
@@ -185,7 +192,7 @@ public class DialogHolder {
switch (dialog.afterAction()) {
case NONE -> {
// If no new dialog was opened, reopen this one
dialog.restoreForm(manager.session(), lastInputs, this);
dialog.restoreForm(this, lastInputs);
}
case CLOSE -> {
// If no new dialog was opened, tell the manager this one is now closed
@@ -212,8 +219,8 @@ public class DialogHolder {
content += " If no new dialog is shown within 5 seconds, a button will appear to go back to the game.";
}
manager.session().sendDialogForm(SimpleForm.builder()
.translator(MinecraftLocale::getLocaleString, manager.session().locale())
session.sendDialogForm(SimpleForm.builder()
.translator(MinecraftLocale::getLocaleString, session.locale())
.title("gui.waitingForResponse.title")
.content(content)
.optionalButton("gui.back", sendBackButton)
@@ -240,22 +247,22 @@ public class DialogHolder {
if (action != null) {
// Ask the user for confirmation if the dialog wants to run an unknown command or a command that requires operator permissions
if (action instanceof DialogAction.CommandAction runCommand) {
String command = runCommand.trimmedCommand(manager.session(), inputs);
String command = runCommand.trimmedCommand(session, inputs);
String root = command.split(" ")[0];
// This check is not perfect. Ideally we'd check the entire command and see if any of its arguments require operator permissions, but, that's complicated
if (manager.session().getRestrictedCommands().contains(root)) {
if (session.getRestrictedCommands().contains(root)) {
showCommandConfirmation(command, false);
return false;
} else if (!manager.session().getKnownCommands().contains(root)) {
} else if (!session.getKnownCommands().contains(root)) {
showCommandConfirmation(command, true);
return false;
}
manager.session().sendCommand(command);
session.sendCommand(command);
return true;
} else {
action.run(manager.session(), inputs);
action.run(session, inputs);
return !(action instanceof DialogAction.ShowDialog);
}
}
@@ -269,10 +276,10 @@ public class DialogHolder {
Component content = Component.translatable(unknown ? "multiplayer.confirm_command.parse_errors" : "multiplayer.confirm_command.permissions_required",
Component.text(trimmedCommand).color(NamedTextColor.YELLOW));
manager.session().sendDialogForm(ModalForm.builder()
.translator(MinecraftLocale::getLocaleString, manager.session().locale())
session.sendDialogForm(ModalForm.builder()
.translator(MinecraftLocale::getLocaleString, session.locale())
.title("multiplayer.confirm_command.title")
.content(MessageTranslator.convertMessage(manager.session(), content))
.content(MessageTranslator.convertMessage(session, content))
.button1("gui.yes")
.button2("gui.no")
.closedOrInvalidResultHandler(() -> {
@@ -282,7 +289,7 @@ public class DialogHolder {
})
.validResultHandler(response -> {
if (response.clickedFirst()) {
manager.session().sendCommand(trimmedCommand);
session.sendCommand(trimmedCommand);
if (shouldClose) {
manager.close();
} else {

View File

@@ -36,7 +36,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.Holder;
*/
@Accessors(fluent = true)
public class DialogManager {
@Getter
private final GeyserSession session;
@Getter
private DialogHolder open;
@@ -53,9 +52,9 @@ public class DialogManager {
* Opens a new dialog. If a dialog was already open, this one will be closed. Its closing action will not be executed. This matches Java behaviour.
*/
public void openDialog(Dialog dialog) {
open = new DialogHolder(this, dialog);
open = new DialogHolder(session, this, dialog);
session.closeForm();
dialog.sendForm(session, open);
dialog.sendForm(open);
}
public void tick() {

View File

@@ -48,7 +48,7 @@ public abstract class DialogWithButtons extends Dialog {
}
@Override
protected void addCustomComponents(GeyserSession session, CustomForm.Builder builder, DialogHolder holder) {
protected void addCustomComponents(DialogHolder holder, CustomForm.Builder builder) {
DropdownComponent.Builder dropdown = DropdownComponent.builder();
dropdown.text("Please select an option:");
for (DialogButton button : buttons) {
@@ -57,20 +57,18 @@ public abstract class DialogWithButtons extends Dialog {
exitAction.ifPresent(button -> dropdown.option(button.label()));
builder.dropdown(dropdown);
builder.validResultHandler(response -> {
parseInput(session, response, holder).ifPresent(inputs -> {
int selection = response.asDropdown();
if (selection == buttons.size()) {
holder.runButton(exitAction, inputs);
} else {
holder.runButton(Optional.of(buttons.get(selection)), inputs);
}
});
});
builder.validResultHandler(response -> parseInput(holder, response).ifPresent(inputs -> {
int selection = response.asDropdown();
if (selection == buttons.size()) {
holder.runButton(exitAction, inputs);
} else {
holder.runButton(Optional.of(buttons.get(selection)), inputs);
}
}));
}
@Override
protected void addCustomComponents(GeyserSession session, SimpleForm.Builder builder, DialogHolder holder) {
protected void addCustomComponents(DialogHolder holder, SimpleForm.Builder builder) {
for (DialogButton button : buttons) {
builder.button(button.label());
}

View File

@@ -52,12 +52,12 @@ public class NoticeDialog extends Dialog {
}
@Override
protected void addCustomComponents(GeyserSession session, CustomForm.Builder builder, DialogHolder holder) {
builder.validResultHandler(response -> parseInput(session, response, holder).ifPresent(inputs -> holder.runButton(button, inputs)));
protected void addCustomComponents(DialogHolder holder, CustomForm.Builder builder) {
builder.validResultHandler(response -> parseInput(holder, response).ifPresent(inputs -> holder.runButton(button, inputs)));
}
@Override
protected void addCustomComponents(GeyserSession session, SimpleForm.Builder builder, DialogHolder holder) {
protected void addCustomComponents(DialogHolder holder, SimpleForm.Builder builder) {
builder.button(button.map(DialogButton::label).orElse("gui.ok"))
.validResultHandler(response -> holder.runButton(button, ParsedInputs.EMPTY));
}

View File

@@ -67,6 +67,8 @@ public interface DialogAction {
return Optional.empty();
}
void run(GeyserSession session, ParsedInputs inputs);
interface CommandAction extends DialogAction {
String command(GeyserSession session, ParsedInputs inputs);
@@ -85,8 +87,6 @@ public interface DialogAction {
}
}
void run(GeyserSession session, ParsedInputs inputs);
record OpenUrl(String url) implements DialogAction {
public static final Key TYPE = MinecraftKey.key("open_url");