From 16901df1766f6459173ff7957ee4964c9bf8c672 Mon Sep 17 00:00:00 2001 From: jojo Date: Wed, 18 Nov 2020 18:36:02 +0100 Subject: [PATCH 1/2] Simplify World Edit Shortcuts --- .../src/de/steamwar/bausystem/BauSystem.java | 19 ++--- .../bausystem/commands/ChainedCommand.java | 75 +++++++++++++++++++ .../commands/worldedit/WECommand.java | 58 -------------- .../commands/worldedit/WECommandCopy.java | 35 --------- .../commands/worldedit/WECommandFlopy.java | 35 --------- .../commands/worldedit/WECommandFlopyp.java | 42 ----------- .../commands/worldedit/WECommandPaste.java | 42 ----------- .../commands/worldedit/WECommandPos1.java | 35 --------- .../commands/worldedit/WECommandPos2.java | 35 --------- .../worldedit/WECommandRotate180.java | 35 --------- .../commands/worldedit/WECommandRotate90.java | 35 --------- .../worldedit/WECommandRotateN90.java | 35 --------- 12 files changed, 85 insertions(+), 396 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/ChainedCommand.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommand.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandCopy.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopy.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopyp.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPaste.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos1.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos2.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate180.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate90.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotateN90.java diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index 7b3d50c..fd71c5a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -49,6 +49,7 @@ import org.bukkit.scheduler.BukkitTask; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.logging.Level; @@ -119,15 +120,15 @@ public class BauSystem extends JavaPlugin implements Listener { getCommand("detonator").setExecutor(new CommandDetonator()); getCommand("detonator").setTabCompleter(new CommandDetonatorTabCompleter()); - getCommand("/1").setExecutor(new WECommandPos1()); - getCommand("/2").setExecutor(new WECommandPos2()); - getCommand("/90").setExecutor(new WECommandRotate90()); - getCommand("/-90").setExecutor(new WECommandRotateN90()); - getCommand("/180").setExecutor(new WECommandRotate180()); - getCommand("/c").setExecutor(new WECommandCopy()); - getCommand("/p").setExecutor(new WECommandPaste()); - getCommand("/flopy").setExecutor(new WECommandFlopy()); - getCommand("/flopyp").setExecutor(new WECommandFlopyp()); + new ChainedCommand("/1", "/pos1"); + new ChainedCommand("/2", "/pos2"); + new ChainedCommand("/90", "/rotate 90"); + new ChainedCommand("/-90", "/rotate -90"); + new ChainedCommand("/180", "/rotate 180"); + new ChainedCommand("/c", "/copy"); + new ChainedCommand("/p", Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"), "/paste {}"); + new ChainedCommand("/flopy", "/copy", "/flip"); + new ChainedCommand("/flopyp", Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"), "/copy", "/flip", "/paste {}"); Bukkit.getPluginManager().registerEvents(this, this); Bukkit.getPluginManager().registerEvents(new RegionListener(), this); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/ChainedCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/ChainedCommand.java new file mode 100644 index 0000000..0bf3018 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/ChainedCommand.java @@ -0,0 +1,75 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class ChainedCommand implements CommandExecutor, TabCompleter { + + private String[] commands; + private List tabCompletes; + + public ChainedCommand(String command, final List tabCompletes, final String... commands) { + BauSystem.getPlugin().getCommand(command).setExecutor(this); + BauSystem.getPlugin().getCommand(command).setTabCompleter(this); + + this.commands = commands; + this.tabCompletes = tabCompletes; + if (tabCompletes == null) { + this.tabCompletes = new ArrayList<>(); + } + } + + public ChainedCommand(String command, final String... commands) { + this(command, null, commands); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + + String argsString = ""; + if (args.length != 0) argsString = String.join(" ", args); + + for (String cmd : commands) { + if (!player.performCommand(cmd.replace("{}", argsString))) { + return false; + } + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String s, String[] args) { + return tabCompletes; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommand.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommand.java deleted file mode 100644 index 069c9e0..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommand.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; - -public abstract class WECommand implements CommandExecutor, TabCompleter { - - @Override - public List onTabComplete(CommandSender sender, Command command, String s, String[] args) { - return new ArrayList<>(); - } - - protected final boolean performCommand(Player p, String command) { - return p.performCommand(command); - } - - protected final boolean performCommands(Player p, String... commands) { - for (String command : commands) { - if (!performCommand(p, command)) return false; - } - return true; - } - - protected final List manageList(List strings, String[] args, int index) { - for (int i = strings.size() - 1; i >= 0; i--) { - if (!strings.get(i).startsWith(args[index])) { - strings.remove(i); - } - } - return strings; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandCopy.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandCopy.java deleted file mode 100644 index 9e6a47f..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandCopy.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandCopy extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/copy"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopy.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopy.java deleted file mode 100644 index 368d091..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopy.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandFlopy extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/copy", "/flip"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopyp.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopyp.java deleted file mode 100644 index fbe190b..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandFlopyp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.Arrays; -import java.util.List; - -public class WECommandFlopyp extends WECommand { - - public List onTabComplete(CommandSender sender, Command command, String s, String[] args) { - return Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/copy", "/flip", "/paste " + String.join(" ", args)); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPaste.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPaste.java deleted file mode 100644 index 0d03519..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPaste.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.Arrays; -import java.util.List; - -public class WECommandPaste extends WECommand { - - public List onTabComplete(CommandSender sender, Command command, String s, String[] args) { - return Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/paste " + String.join(" ", args)); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos1.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos1.java deleted file mode 100644 index b32f60b..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos1.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandPos1 extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/pos1"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos2.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos2.java deleted file mode 100644 index ecb0046..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandPos2.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandPos2 extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/pos2"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate180.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate180.java deleted file mode 100644 index e38dc7f..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate180.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandRotate180 extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/rotate 180"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate90.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate90.java deleted file mode 100644 index 6c6397f..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotate90.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandRotate90 extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/rotate 90"); - return false; - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotateN90.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotateN90.java deleted file mode 100644 index 236b2a2..0000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/worldedit/WECommandRotateN90.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.bausystem.commands.worldedit; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class WECommandRotateN90 extends WECommand { - - @Override - public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { - if (!(sender instanceof Player)) return false; - performCommands((Player) sender, "/rotate -90"); - return false; - } - -} -- 2.39.5 From fce4a646256e127f7a73a69ae5326cb3ca5d2023 Mon Sep 17 00:00:00 2001 From: jojo Date: Wed, 18 Nov 2020 19:51:53 +0100 Subject: [PATCH 2/2] Add //u -> //undo Add //r -> //redo --- BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java | 3 ++- BauSystem_Main/src/plugin.yml | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index fd71c5a..267533f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -20,7 +20,6 @@ package de.steamwar.bausystem; import de.steamwar.bausystem.commands.*; -import de.steamwar.bausystem.commands.worldedit.*; import de.steamwar.bausystem.tracer.ShowManager; import de.steamwar.bausystem.tracer.TNTTracer; import de.steamwar.bausystem.tracer.TraceListener; @@ -129,6 +128,8 @@ public class BauSystem extends JavaPlugin implements Listener { new ChainedCommand("/p", Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"), "/paste {}"); new ChainedCommand("/flopy", "/copy", "/flip"); new ChainedCommand("/flopyp", Arrays.asList("-a", "-b", "-e", "-n", "-o", "-s", "-m"), "/copy", "/flip", "/paste {}"); + new ChainedCommand("/u", "/undo {}"); + new ChainedCommand("/r", "/redo {}"); Bukkit.getPluginManager().registerEvents(this, this); Bukkit.getPluginManager().registerEvents(new RegionListener(), this); diff --git a/BauSystem_Main/src/plugin.yml b/BauSystem_Main/src/plugin.yml index ce245cb..c167863 100644 --- a/BauSystem_Main/src/plugin.yml +++ b/BauSystem_Main/src/plugin.yml @@ -43,3 +43,5 @@ commands: /c: /flopy: /flopyp: + /u: + /r: -- 2.39.5