Skip to content

Commit f6b0234

Browse files
seijikunme4502
authored andcommitted
Add command suggestions for schematic filenames
1 parent 7b79477 commit f6b0234

3 files changed

Lines changed: 99 additions & 4 deletions

File tree

worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,15 @@ public SchematicCommands(WorldEdit worldEdit) {
111111
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load"})
112112
public void load(Actor actor, LocalSession session,
113113
@Arg(desc = "File name.")
114-
String filename,
114+
Schematic schematic,
115115
@Arg(desc = "Format name.", def = "sponge")
116116
ClipboardFormat format) throws FilenameException {
117117
LocalConfiguration config = worldEdit.getConfiguration();
118118

119-
File dir = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile();
120-
File f = worldEdit.getSafeOpenFile(actor, dir, filename,
119+
// Schematic.path is relative, so treat it as filename
120+
String filename = schematic.getPath().toString();
121+
File schematicsRoot = worldEdit.getSchematicsManager().getRoot().toFile();
122+
File f = worldEdit.getSafeOpenFile(actor, schematicsRoot, filename,
121123
BuiltInClipboardFormat.SPONGE_V3_SCHEMATIC.getPrimaryFileExtension(),
122124
ClipboardFormats.getFileExtensionArray());
123125

@@ -249,10 +251,12 @@ public void share(Actor actor, LocalSession session,
249251
@CommandPermissions("worldedit.schematic.delete")
250252
public void delete(Actor actor,
251253
@Arg(desc = "File name.")
252-
String filename) throws WorldEditException {
254+
Schematic schematic) throws WorldEditException {
253255
LocalConfiguration config = worldEdit.getConfiguration();
254256
File dir = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile();
255257

258+
// Schematic.path is relative, so treat it as filename
259+
String filename = schematic.getPath().toString();
256260
File f = worldEdit.getSafeOpenFile(actor,
257261
dir, filename, "schematic", ClipboardFormats.getFileExtensionArray());
258262

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* WorldEdit, a Minecraft world manipulation toolkit
3+
* Copyright (C) sk89q <http://www.sk89q.com>
4+
* Copyright (C) WorldEdit team and contributors
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
package com.sk89q.worldedit.command.argument;
21+
22+
import com.sk89q.worldedit.WorldEdit;
23+
import com.sk89q.worldedit.internal.util.LogManagerCompat;
24+
import com.sk89q.worldedit.util.formatting.text.Component;
25+
import com.sk89q.worldedit.util.formatting.text.TextComponent;
26+
import com.sk89q.worldedit.util.io.file.FilenameException;
27+
import com.sk89q.worldedit.util.schematic.Schematic;
28+
import com.sk89q.worldedit.util.schematic.SchematicsManager;
29+
import org.enginehub.piston.CommandManager;
30+
import org.enginehub.piston.converter.ArgumentConverter;
31+
import org.enginehub.piston.converter.ConversionResult;
32+
import org.enginehub.piston.converter.FailedConversion;
33+
import org.enginehub.piston.converter.SuccessfulConversion;
34+
import org.enginehub.piston.inject.InjectedValueAccess;
35+
import org.enginehub.piston.inject.Key;
36+
37+
import java.nio.file.Files;
38+
import java.nio.file.Path;
39+
import java.util.List;
40+
41+
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
42+
43+
public class SchematicConverter implements ArgumentConverter<Schematic> {
44+
45+
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
46+
commandManager.registerConverter(Key.of(Schematic.class), new SchematicConverter(worldEdit));
47+
}
48+
49+
private final WorldEdit worldEdit;
50+
51+
private SchematicConverter(WorldEdit worldEdit) {
52+
this.worldEdit = worldEdit;
53+
}
54+
55+
private final TextComponent choices = TextComponent.of("schematic filename");
56+
57+
@Override
58+
public Component describeAcceptableArguments() {
59+
return choices;
60+
}
61+
62+
@Override
63+
public List<String> getSuggestions(String input, InjectedValueAccess context) {
64+
SchematicsManager schematicsManager = worldEdit.getSchematicsManager();
65+
Path schematicsRootPath = schematicsManager.getRoot();
66+
67+
return limitByPrefix(schematicsManager.getList().stream()
68+
.map(s -> schematicsRootPath.relativize(s.getPath()).toString()), input);
69+
}
70+
71+
@Override
72+
public ConversionResult<Schematic> convert(String s, InjectedValueAccess injectedValueAccess) {
73+
Path schematicsRoot = worldEdit.getSchematicsManager().getRoot();
74+
// resolve as subpath of schematicsRoot
75+
Path schematicPath = schematicsRoot.resolve(s).toAbsolutePath();
76+
// then check whether it is still a subpath to rule out "../"
77+
if (!schematicPath.startsWith(schematicsRoot)) {
78+
return FailedConversion.from(new FilenameException(s));
79+
}
80+
// check whether the file exists
81+
if (Files.exists(schematicPath)) {
82+
// continue as relative path to schematicsRoot
83+
schematicPath = schematicsRoot.relativize(schematicPath);
84+
return SuccessfulConversion.fromSingle(new Schematic(schematicPath));
85+
} else {
86+
return FailedConversion.from(new FilenameException(s));
87+
}
88+
}
89+
}

worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import com.sk89q.worldedit.command.argument.OffsetConverter;
8383
import com.sk89q.worldedit.command.argument.RegionFactoryConverter;
8484
import com.sk89q.worldedit.command.argument.RegistryConverter;
85+
import com.sk89q.worldedit.command.argument.SchematicConverter;
8586
import com.sk89q.worldedit.command.argument.SelectorChoiceConverter;
8687
import com.sk89q.worldedit.command.argument.SideEffectConverter;
8788
import com.sk89q.worldedit.command.argument.SideEffectSetConverter;
@@ -232,6 +233,7 @@ private void registerArgumentConverters() {
232233
ClipboardFormatConverter.register(commandManager);
233234
ClipboardShareDestinationConverter.register(commandManager);
234235
SelectorChoiceConverter.register(commandManager);
236+
SchematicConverter.register(worldEdit, commandManager);
235237
}
236238

237239
private void registerAlwaysInjectedValues() {

0 commit comments

Comments
 (0)