Skip to content

Commit 90764ad

Browse files
committed
add query command
1 parent ddda007 commit 90764ad

File tree

5 files changed

+162
-17
lines changed

5 files changed

+162
-17
lines changed

common/src/main/java/com/github/litermc/vschunkloader/VSCApi.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import com.github.litermc.vschunkloader.attachment.ForceLoadAttachment;
44

5+
import net.minecraft.resources.ResourceLocation;
56
import net.minecraft.server.MinecraftServer;
67
import net.minecraft.server.level.ServerLevel;
78

89
import org.valkyrienskies.core.api.ships.ServerShip;
910
import org.valkyrienskies.core.api.world.ServerShipWorld;
1011
import org.valkyrienskies.mod.common.VSGameUtilsKt;
1112

13+
import java.util.Set;
14+
1215
public final class VSCApi {
1316
private static final VSCApi INSTANCE = new VSCApi();
1417

@@ -23,13 +26,14 @@ public static VSCApi get() {
2326
*
2427
* @param server The {@link MinecraftServer} instance
2528
* @param id The ship's ID
26-
* @param token Force load token, same token must be used when invoking {@link stopForceLoadShip}
29+
* @param token Force load token, same token must be used when invoking {@link stopForceLoadShip}.
30+
* The namespace of the token must be the mod's ID.
2731
* @param load {@code true} if force loading ship, {@code false} if unloading
2832
* @return {@code true} if the token is updated, or {@code false} if ship is not found
2933
*
3034
* @see stopForceLoadShip
3135
*/
32-
public static boolean forceLoad(final MinecraftServer server, final long id, final String token, final boolean load) {
36+
public static boolean forceLoad(final MinecraftServer server, final long id, final ResourceLocation token, final boolean load) {
3337
final ServerShip ship = getShip(server, id);
3438
if (ship == null) {
3539
return false;
@@ -52,7 +56,7 @@ public static boolean forceLoad(final MinecraftServer server, final long id, fin
5256
*
5357
* @see stopForceLoadShip
5458
*/
55-
public static boolean stopAllForceLoading(final MinecraftServer server, final long id) {
59+
public static boolean clearForceLoadTokens(final MinecraftServer server, final long id) {
5660
final ServerShip ship = getShip(server, id);
5761
if (ship == null) {
5862
return false;
@@ -62,6 +66,23 @@ public static boolean stopAllForceLoading(final MinecraftServer server, final lo
6266
return true;
6367
}
6468

69+
/**
70+
* gets a read-only view of the tokens of a ship.<br/>
71+
* The set can be modified later by other methods in this API.
72+
*
73+
* @param server The {@link MinecraftServer} instance
74+
* @param id The ship's ID
75+
* @return {@code null} if the ship is not found, or a unmodifiable set of current loading ticket.
76+
*/
77+
public static Set<ResourceLocation> getForceLoadTokens(final MinecraftServer server, final long id) {
78+
final ServerShip ship = getShip(server, id);
79+
if (ship == null) {
80+
return null;
81+
}
82+
final ForceLoadAttachment attachment = ForceLoadAttachment.get(ship);
83+
return attachment.getAllForceLoadTokens();
84+
}
85+
6586
/**
6687
* check if a ship is force loaded
6788
*
@@ -85,7 +106,7 @@ public static boolean isForceLoaded(final MinecraftServer server, final long id)
85106
* @param token Force load token, should be already used in {@link forceLoadShip}
86107
* @return whether or not the ship is force loaded by the token
87108
*/
88-
public static boolean isForceLoadedBy(final MinecraftServer server, final long id, final String token) {
109+
public static boolean isForceLoadedBy(final MinecraftServer server, final long id, final ResourceLocation token) {
89110
final ServerShip ship = getShip(server, id);
90111
if (ship == null) {
91112
return false;

common/src/main/java/com/github/litermc/vschunkloader/attachment/ForceLoadAttachment.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.github.litermc.vschunkloader.attachment;
22

3+
import com.github.litermc.vschunkloader.util.ResourceLocationCollectionSerializer;
4+
5+
import net.minecraft.resources.ResourceLocation;
6+
37
import com.fasterxml.jackson.annotation.JsonAutoDetect;
8+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
49
import org.valkyrienskies.core.api.ships.ServerShip;
510

11+
import java.util.Collections;
612
import java.util.HashSet;
713
import java.util.Set;
814

@@ -12,7 +18,8 @@
1218
isGetterVisibility = JsonAutoDetect.Visibility.NONE
1319
)
1420
public final class ForceLoadAttachment {
15-
private Set<String> forceLoadTokens = new HashSet<>();
21+
@JsonSerialize(using = ResourceLocationCollectionSerializer.class)
22+
private Set<ResourceLocation> forceLoadTokens = new HashSet<>();
1623

1724
public ForceLoadAttachment() {}
1825

@@ -29,19 +36,23 @@ public boolean isForceLoaded() {
2936
return !this.forceLoadTokens.isEmpty();
3037
}
3138

32-
public boolean isForceLoadedBy(final String token) {
39+
public boolean isForceLoadedBy(final ResourceLocation token) {
3340
return this.forceLoadTokens.contains(token);
3441
}
3542

36-
public void addForceLoad(final String token) {
43+
public void addForceLoad(final ResourceLocation token) {
3744
this.forceLoadTokens.add(token);
3845
}
3946

40-
public void removeForceLoad(final String token) {
47+
public void removeForceLoad(final ResourceLocation token) {
4148
this.forceLoadTokens.remove(token);
4249
}
4350

4451
public void removeAllForceLoadTokens() {
4552
this.forceLoadTokens.clear();
4653
}
54+
55+
public Set<ResourceLocation> getAllForceLoadTokens() {
56+
return Collections.unmodifiableSet(this.forceLoadTokens);
57+
}
4758
}

common/src/main/java/com/github/litermc/vschunkloader/command/VSCCommands.java

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import net.minecraft.commands.CommandSourceStack;
1111
import net.minecraft.commands.Commands;
1212
import net.minecraft.network.chat.Component;
13+
import net.minecraft.network.chat.MutableComponent;
14+
import net.minecraft.resources.ResourceLocation;
1315
import net.minecraft.server.MinecraftServer;
1416

1517
import org.valkyrienskies.core.api.ships.Ship;
@@ -20,6 +22,7 @@
2022

2123
public final class VSCCommands {
2224
public static final String ROOT_LITERAL = "vschunkloader";
25+
public static final ResourceLocation FORCELOAD_TOKEN = new ResourceLocation(Constants.MOD_ID, "command");
2326

2427
private VSCCommands() {}
2528

@@ -28,33 +31,81 @@ public static void register(final CommandDispatcher<CommandSourceStack> dispatch
2831
.requires((source) -> source.hasPermission(2))
2932
.then(Commands.literal("forceload")
3033
.then(Commands.argument("ships", ShipArgument.Companion.ships())
31-
.then(Commands.argument("forceload", BoolArgumentType.bool())
32-
.executes(VSCCommands::setForceLoad)
33-
)
34+
.executes(VSCCommands::forceLoad)
35+
)
36+
)
37+
.then(Commands.literal("unforceload")
38+
.then(Commands.argument("ships", ShipArgument.Companion.ships())
39+
.executes(VSCCommands::unforceLoad)
40+
)
41+
)
42+
.then(Commands.literal("unforceload-all")
43+
.then(Commands.argument("ships", ShipArgument.Companion.ships())
44+
.executes(VSCCommands::unforceLoadAll)
3445
)
3546
)
3647
.then(Commands.literal("is-forceloaded")
3748
.then(Commands.argument("ships", ShipArgument.Companion.ships())
3849
.executes(VSCCommands::isForceLoaded)
3950
)
4051
)
52+
.then(Commands.literal("query-forceload-tokens")
53+
.then(Commands.argument("ships", ShipArgument.Companion.ships())
54+
.executes(VSCCommands::queryForceLoadTokens)
55+
)
56+
)
57+
);
58+
}
59+
60+
private static int forceLoad(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
61+
final CommandSourceStack source = context.getSource();
62+
final MinecraftServer server = source.getServer();
63+
final Set<Ship> ships = ShipArgument.Companion.getShips((CommandContext<VSCommandSource>)((CommandContext<?>)(context)), "ships");
64+
int successCount = 0;
65+
for (final Ship ship : ships) {
66+
if (VSCApi.forceLoad(server, ship.getId(), FORCELOAD_TOKEN, true)) {
67+
successCount++;
68+
}
69+
}
70+
final int finalSuccessCount = successCount;
71+
source.sendSuccess(() ->
72+
Component.translatable("command." + Constants.MOD_ID + ".forceload", finalSuccessCount),
73+
true
74+
);
75+
return finalSuccessCount;
76+
}
77+
78+
private static int unforceLoad(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
79+
final CommandSourceStack source = context.getSource();
80+
final MinecraftServer server = source.getServer();
81+
final Set<Ship> ships = ShipArgument.Companion.getShips((CommandContext<VSCommandSource>)((CommandContext<?>)(context)), "ships");
82+
int successCount = 0;
83+
for (final Ship ship : ships) {
84+
if (VSCApi.forceLoad(server, ship.getId(), FORCELOAD_TOKEN, false)) {
85+
successCount++;
86+
}
87+
}
88+
final int finalSuccessCount = successCount;
89+
source.sendSuccess(() ->
90+
Component.translatable("command." + Constants.MOD_ID + ".unforceload", finalSuccessCount),
91+
true
4192
);
93+
return finalSuccessCount;
4294
}
4395

44-
private static int setForceLoad(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
96+
private static int unforceLoadAll(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
4597
final CommandSourceStack source = context.getSource();
4698
final MinecraftServer server = source.getServer();
4799
final Set<Ship> ships = ShipArgument.Companion.getShips((CommandContext<VSCommandSource>)((CommandContext<?>)(context)), "ships");
48-
final boolean forceload = BoolArgumentType.getBool(context, "forceload");
49100
int successCount = 0;
50101
for (final Ship ship : ships) {
51-
if (VSCApi.forceLoad(server, ship.getId(), Constants.MOD_ID, forceload)) {
102+
if (VSCApi.clearForceLoadTokens(server, ship.getId())) {
52103
successCount++;
53104
}
54105
}
55106
final int finalSuccessCount = successCount;
56107
source.sendSuccess(() ->
57-
Component.translatable("command." + Constants.MOD_ID + ".forceload." + (forceload ? "load" : "unload"), finalSuccessCount),
108+
Component.translatable("command." + Constants.MOD_ID + ".unforceload", finalSuccessCount),
58109
true
59110
);
60111
return finalSuccessCount;
@@ -79,4 +130,39 @@ private static int isForceLoaded(final CommandContext<CommandSourceStack> contex
79130
);
80131
return finalLoadedCount;
81132
}
133+
134+
private static int queryForceLoadTokens(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
135+
final CommandSourceStack source = context.getSource();
136+
final MinecraftServer server = source.getServer();
137+
final Set<Ship> ships = ShipArgument.Companion.getShips((CommandContext<VSCommandSource>)((CommandContext<?>)(context)), "ships");
138+
if (ships.isEmpty()) {
139+
source.sendFailure(Component.translatable("argument.valkyrienskies.ship.no_found"));
140+
return 0;
141+
}
142+
if (ships.size() > 1) {
143+
source.sendFailure(Component.translatable("argument.valkyrienskies.ship.multiple_found"));
144+
return 0;
145+
}
146+
final Ship ship = ships.iterator().next();
147+
final Set<ResourceLocation> tokens = VSCApi.getForceLoadTokens(server, ship.getId());
148+
if (tokens == null) {
149+
source.sendFailure(Component.translatable("argument.valkyrienskies.ship.no_found"));
150+
return 0;
151+
}
152+
final int count = tokens.size();
153+
if (count == 0) {
154+
source.sendSuccess(() -> Component.translatable("command." + Constants.MOD_ID + ".query_forceload.none"), false);
155+
return 1;
156+
}
157+
source.sendSuccess(() -> {
158+
final MutableComponent component = Component.translatable("command." + Constants.MOD_ID + ".query_forceload.title", count);
159+
tokens.stream()
160+
.map(ResourceLocation::toString)
161+
.sorted()
162+
.map((token) -> Component.literal("\n- ").append(token))
163+
.forEach(component::append);
164+
return component;
165+
}, false);
166+
return count + 1;
167+
}
82168
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.litermc.vschunkloader.util;
2+
3+
import net.minecraft.resources.ResourceLocation;
4+
5+
import com.fasterxml.jackson.core.JsonGenerator;
6+
import com.fasterxml.jackson.databind.JsonSerializer;
7+
import com.fasterxml.jackson.databind.SerializerProvider;
8+
9+
import java.io.IOException;
10+
import java.util.Collection;
11+
12+
public class ResourceLocationCollectionSerializer extends JsonSerializer<Collection<ResourceLocation>> {
13+
@Override
14+
public void serialize(
15+
final Collection<ResourceLocation> locations,
16+
final JsonGenerator generator,
17+
final SerializerProvider serializers
18+
) throws IOException {
19+
generator.writeStartArray();
20+
for (final ResourceLocation location : locations) {
21+
generator.writeString(location.toString());
22+
}
23+
generator.writeEndArray();
24+
}
25+
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"block.vschunkloader.chunk_loader": "Chunk Loader",
33
"block.vschunkloader.chunk_loader_weak": "Weak Chunk Loader",
4-
"command.vschunkloader.forceload.load": "Successfully force loaded %d ships",
5-
"command.vschunkloader.forceload.unload": "Successfully released force load on %d ships",
4+
"command.vschunkloader.forceload": "Successfully force loaded %d ships",
5+
"command.vschunkloader.unforceload": "Successfully released force load on %d ships",
66
"command.vschunkloader.is_forceloaded": "There are %d ships force loading",
77
"command.vschunkloader.is_forceloaded.none": "No ship is force loaded",
8+
"command.vschunkloader.query_forceload.none": "The ship is not force loaded",
9+
"command.vschunkloader.query_forceload.title": "The ship has %d force load tokens:",
810
"itemGroup.vschunkloader": "VS Chunk Loader"
911
}

0 commit comments

Comments
 (0)