Skip to content

Commit 859c502

Browse files
committed
feat: Add admin commands for network management (#305)
Add comprehensive admin/OP command system for managing logistics networks: - /cmp network list: Display all networks with details * Shows network name, short ID, player count * Displays lock status and owner information * Only lists named networks (filters out unnamed networks) - /cmp network add <player> <networkId>: Add a player to a network * Argument order: player first, then network ID * Auto-completes to named networks only * Prevents adding players to unnamed networks - /cmp network remove <player> <networkId>: Remove a player from a network * Argument order: player first, then network ID * Auto-completes to networks the player is part of * Prevents removing players from networks they're not in Features: - Full command auto-completion with intelligent filtering - Clear success feedback messages - Admin/OP permission level 2 requirement for all commands - Null-safe checks for player lookups and network data Resolves server owner requests for easier network management on larger servers.
1 parent 9fc1f4e commit 859c502

2 files changed

Lines changed: 126 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ Create: Mobile Packages - v0.7.0 - 1.21.1 - unreleased
44

55
### Additions
66

7+
- Added Admin/OP Commands for Network Management (#305)
8+
- `/cmp network list` - Display all logistics networks with names, player counts, lock status, and owner information
9+
- `/cmp network add <player> <networkId>` - Add a player to a network (auto-filters to named networks only)
10+
- `/cmp network remove <player> <networkId>` - Remove a player from a network (auto-filters to networks the player is
11+
part of)
12+
- Full command auto-completion with intelligent filtering
13+
714
- Added TrashSlots to the Portable Stock Ticker allowing players to send items (#299)
815
- Set an address
916
- Put items in the TrashSlots

src/main/java/de/theidler/create_mobile_packages/index/CMPCommands.java

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
import com.mojang.brigadier.CommandDispatcher;
44
import com.mojang.brigadier.arguments.StringArgumentType;
55
import com.mojang.brigadier.context.CommandContext;
6+
import com.simibubi.create.Create;
7+
import de.theidler.create_mobile_packages.IExtendedLogisticsNetwork;
8+
import de.theidler.create_mobile_packages.network_settings.AddPlayerToNetworkPackage;
9+
import de.theidler.create_mobile_packages.network_settings.NetworkHelper;
10+
import de.theidler.create_mobile_packages.network_settings.RemovePlayerFromNetworkPackage;
611
import de.theidler.create_mobile_packages.robo.RoboManager;
7-
import de.theidler.create_mobile_packages.toast.types.SimpleToast;
812
import de.theidler.create_mobile_packages.toast.RemoveAllToastsOnClientPacket;
913
import de.theidler.create_mobile_packages.toast.ShowToastOnClientPacket;
14+
import de.theidler.create_mobile_packages.toast.types.SimpleToast;
1015
import net.createmod.catnip.platform.CatnipServices;
1116
import net.minecraft.commands.CommandSourceStack;
1217
import net.minecraft.commands.Commands;
18+
import net.minecraft.commands.arguments.EntityArgument;
1319
import net.minecraft.network.chat.Component;
1420
import net.minecraft.server.level.ServerLevel;
1521
import net.minecraft.server.level.ServerPlayer;
22+
import net.minecraft.world.entity.player.Player;
1623

1724
import java.util.UUID;
1825

@@ -47,9 +54,100 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
4754
.executes(CMPCommands::clearRobos)
4855
)
4956
)
57+
.then(
58+
Commands.literal("network")
59+
.requires(cs -> cs.hasPermission(2)) // admin only
60+
.then(
61+
Commands.literal("list")
62+
.executes(CMPCommands::showAllNetworks)
63+
)
64+
.then(
65+
Commands.literal("add")
66+
.then(
67+
Commands.argument("player", EntityArgument.player())
68+
.then(
69+
Commands.argument("networkId", StringArgumentType.word())
70+
.suggests((ctx, builder) -> {
71+
Create.LOGISTICS.logisticsNetworks.forEach((uuid, value) -> {
72+
IExtendedLogisticsNetwork extendedNetwork = NetworkHelper.getExtendedLogisticsNetwork(value);
73+
String name = extendedNetwork != null ? extendedNetwork.create_mobile_packages$getName() : "Unnamed Network";
74+
if (!name.equals("Unnamed Network")) {
75+
builder.suggest(uuid.toString());
76+
}
77+
});
78+
return builder.buildFuture();
79+
})
80+
.executes(ctx -> addPlayerToNetwork(ctx,
81+
EntityArgument.getPlayer(ctx, "player"),
82+
UUID.fromString(StringArgumentType.getString(ctx, "networkId"))))
83+
)
84+
)
85+
)
86+
.then(
87+
Commands.literal("remove")
88+
.then(
89+
Commands.argument("player", EntityArgument.player())
90+
.then(
91+
Commands.argument("networkId", StringArgumentType.word())
92+
.suggests((ctx, builder) -> {
93+
ServerPlayer player = EntityArgument.getPlayer(ctx, "player");
94+
Create.LOGISTICS.logisticsNetworks.forEach((key, value) -> {
95+
IExtendedLogisticsNetwork extendedNetwork = NetworkHelper.getExtendedLogisticsNetwork(value);
96+
if (extendedNetwork != null && extendedNetwork.create_mobile_packages$getPlayers().contains(player.getUUID())) {
97+
builder.suggest(key.toString());
98+
}
99+
});
100+
return builder.buildFuture();
101+
})
102+
.executes(ctx -> removePlayerFromNetwork(ctx,
103+
EntityArgument.getPlayer(ctx, "player"),
104+
UUID.fromString(StringArgumentType.getString(ctx, "networkId"))))
105+
)
106+
)
107+
)
108+
)
50109
);
51110
}
52111

112+
private static int showAllNetworks(CommandContext<CommandSourceStack> context) {
113+
CommandSourceStack source = context.getSource();
114+
ServerLevel level = source.getLevel();
115+
116+
if (Create.LOGISTICS.logisticsNetworks.isEmpty()) {
117+
source.sendSuccess(() -> Component.literal("No logistics networks found."), false);
118+
return 0;
119+
}
120+
121+
StringBuilder output = new StringBuilder("═══════════════════════════════════\n");
122+
output.append("Logistics Networks:\n");
123+
124+
for (var entry : Create.LOGISTICS.logisticsNetworks.entrySet()) {
125+
UUID networkId = entry.getKey();
126+
var logisticsNetwork = entry.getValue();
127+
IExtendedLogisticsNetwork extendedNetwork = NetworkHelper.getExtendedLogisticsNetwork(logisticsNetwork);
128+
129+
String name = extendedNetwork != null ? extendedNetwork.create_mobile_packages$getName() : "Unnamed Network";
130+
if (name.equals("Unnamed Network")) continue; // Skip unnamed networks
131+
132+
int playerCount = extendedNetwork.create_mobile_packages$getPlayers().size();
133+
boolean isLocked = logisticsNetwork.locked;
134+
Player owner = level.getPlayerByUUID(logisticsNetwork.owner);
135+
String ownerName = owner != null ? owner.getName().getString() : "Unknown";
136+
137+
String shortId = networkId.toString().substring(0, 8);
138+
output.append("\n▸ ").append(name)
139+
.append(" | ID: ").append(shortId).append("...")
140+
.append("\n └─ Players: ").append(playerCount)
141+
.append(" | Status: ").append(isLocked ? "🔒 Locked" : "🔓 Unlocked")
142+
.append(" | Owner: ").append(ownerName);
143+
}
144+
145+
output.append("\n═══════════════════════════════════");
146+
String finalOutput = output.toString();
147+
source.sendSuccess(() -> Component.literal(finalOutput), false);
148+
return 1;
149+
}
150+
53151
private static int clearRobos(CommandContext<CommandSourceStack> context) {
54152
CommandSourceStack source = context.getSource();
55153
ServerLevel level = source.getLevel();
@@ -78,4 +176,24 @@ private static int clearToasts(CommandContext<CommandSourceStack> context) {
78176
CatnipServices.NETWORK.sendToClient(player, RemoveAllToastsOnClientPacket.INSTANCE);
79177
return 1;
80178
}
179+
180+
private static int addPlayerToNetwork(CommandContext<CommandSourceStack> context, ServerPlayer targetPlayer, UUID networkId) {
181+
CommandSourceStack source = context.getSource();
182+
183+
AddPlayerToNetworkPackage packet = new AddPlayerToNetworkPackage(targetPlayer.getUUID(), networkId);
184+
CatnipServices.NETWORK.sendToServer(packet);
185+
186+
source.sendSuccess(() -> Component.literal("Added player " + targetPlayer.getName().getString() + " to network " + networkId), true);
187+
return 1;
188+
}
189+
190+
private static int removePlayerFromNetwork(CommandContext<CommandSourceStack> context, ServerPlayer targetPlayer, UUID networkId) {
191+
CommandSourceStack source = context.getSource();
192+
193+
RemovePlayerFromNetworkPackage packet = new RemovePlayerFromNetworkPackage(targetPlayer.getUUID(), networkId);
194+
CatnipServices.NETWORK.sendToServer(packet);
195+
196+
source.sendSuccess(() -> Component.literal("Removed player " + targetPlayer.getName().getString() + " from network " + networkId), true);
197+
return 1;
198+
}
81199
}

0 commit comments

Comments
 (0)