Skip to content

Commit 3b94199

Browse files
committed
Merge branch '5.2' into feat/import-playerdata
# Conflicts: # src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt
2 parents 17fa61c + f2dc11f commit 3b94199

17 files changed

+1495
-50
lines changed

build.gradle

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id 'checkstyle'
3-
id 'org.mvplugins.multiverse-plugin' version '1.1.0'
3+
id 'org.mvplugins.multiverse-plugin' version '1.2.1'
44
}
55

66
group = 'org.mvplugins.multiverse.inventories'
@@ -29,23 +29,18 @@ repositories {
2929
}
3030

3131
configure(apiDependencies) {
32-
serverApiVersion = '1.21.3-R0.1-SNAPSHOT'
32+
serverApiVersion = '1.21.8-R0.1-SNAPSHOT'
3333
mockBukkitServerApiVersion = '1.21'
3434
mockBukkitVersion = '4.31.1'
3535
}
3636

3737
dependencies {
38-
// Server API
39-
// TODO make our custom plugin target paper instead of spigot
40-
externalPlugin 'io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT'
41-
4238
// Core
43-
// TODO update to correct version once we have it published
44-
externalPlugin 'org.mvplugins.multiverse.core:multiverse-core:5.2.0-SNAPSHOT'
39+
externalPlugin 'org.mvplugins.multiverse.core:multiverse-core:5.2.0'
4540

4641
// Config
4742
shadowed 'com.dumptruckman.minecraft:JsonConfiguration:1.2-SNAPSHOT'
48-
shadowed 'net.minidev:json-smart:2.5.1'
43+
shadowed 'net.minidev:json-smart:2.6.0'
4944

5045
// Utils
5146
shadowed('com.dumptruckman.minecraft:Logging:1.1.1') {
@@ -54,7 +49,7 @@ dependencies {
5449
shadowed 'com.viaversion:nbt:5.1.1'
5550

5651
// Caching
57-
shadowed("com.github.ben-manes.caffeine:caffeine:3.2.0")
52+
shadowed("com.github.ben-manes.caffeine:caffeine:3.2.2")
5853

5954
// PlaceholderAPI
6055
externalPlugin 'me.clip:placeholderapi:2.11.6'
@@ -75,11 +70,11 @@ dependencies {
7570
}
7671

7772
// hk2 for annotation processing only
78-
compileOnly('org.glassfish.hk2:hk2-api:3.0.3') {
73+
compileOnly('org.glassfish.hk2:hk2-api:3.1.1') {
7974
exclude group: '*', module: '*'
8075
}
81-
annotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.0.3'
82-
testAnnotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.0.3'
76+
annotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.1.1'
77+
testAnnotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.1.1'
8378
}
8479

8580
shadowJar {

src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
@Service
4545
public class MultiverseInventories extends MultiverseModule {
4646

47-
private static final double TARGET_CORE_API_VERSION = 5.0;
47+
private static final double TARGET_CORE_API_VERSION = 5.2;
4848

4949
@Inject
5050
private Provider<CoreConfig> coreConfig;

src/main/java/org/mvplugins/multiverse/inventories/commands/InfoCommand.java

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager;
2323
import org.mvplugins.multiverse.inventories.util.MVInvi18n;
2424

25+
import java.util.Collection;
2526
import java.util.List;
2627
import java.util.Set;
2728

@@ -44,7 +45,7 @@ class InfoCommand extends InventoriesCommand {
4445

4546
@Subcommand("info")
4647
@CommandPermission("multiverse.inventories.info")
47-
@CommandCompletion("@mvworlds")
48+
@CommandCompletion("@mvworlds|@worldGroups")
4849
@Syntax("<world|group>")
4950
@Description("World and Group Information")
5051
void onInfoCommand(
@@ -81,39 +82,26 @@ void onInfoCommand(
8182
}
8283

8384
private void groupInfo(MVCommandIssuer issuer, WorldGroup worldGroup) {
84-
StringBuilder worldsString = new StringBuilder();
8585
Set<String> worlds = worldGroup.getConfigWorlds();
86-
if (worlds.isEmpty()) {
87-
worldsString.append("N/A");
88-
} else {
89-
for (String world : worlds) {
90-
if (!worldsString.toString().isEmpty()) {
91-
worldsString.append(", ");
92-
}
93-
worldsString.append(world);
94-
}
95-
}
96-
//todo: Better messaging formatting here
97-
issuer.sendMessage("Applicable Worlds: " + StringFormatter.join(worldGroup.getApplicableWorlds(), ", "));
98-
issuer.sendInfo(MVInvi18n.INFO_GROUP_INFO, replace("{worlds}").with(worldsString));
99-
issuer.sendInfo(MVInvi18n.INFO_GROUP_INFOSHARES, replace("{shares}").with(worldGroup.getShares()));
86+
issuer.sendMessage(MVInvi18n.INFO_GROUP_INFO, replace("{worlds}").with(formatStringList(worlds)));
87+
issuer.sendMessage(MVInvi18n.INFO_GROUP_APPLICABLEWORLDS, replace("{worlds}").with(formatStringList(worldGroup.getApplicableWorlds())));
88+
issuer.sendMessage(MVInvi18n.INFO_GROUP_INFOSHARES, replace("{shares}").with(worldGroup.getShares()));
89+
issuer.sendMessage(MVInvi18n.INFO_GROUP_APPLICABLESHARES, replace("{shares}").with(worldGroup.getApplicableShares()));
10090
}
10191

10292
private void worldInfo(MVCommandIssuer issuer, ProfileContainer worldProfileContainer) {
103-
StringBuilder groupsString = new StringBuilder();
104-
List<WorldGroup> worldGroups = worldGroupManager.getGroupsForWorld(worldProfileContainer.getContainerName());
93+
List<String> worldGroupNames = worldGroupManager.getGroupsForWorld(worldProfileContainer.getContainerName())
94+
.stream()
95+
.map(WorldGroup::getName)
96+
.toList();
97+
issuer.sendInfo(MVInvi18n.INFO_WORLD_INFO, replace("{groups}").with(formatStringList(worldGroupNames)));
98+
}
10599

106-
if (worldGroups.isEmpty()) {
107-
groupsString.append("N/A");
108-
} else {
109-
for (WorldGroup worldGroup : worldGroups) {
110-
if (!groupsString.toString().isEmpty()) {
111-
groupsString.append(", ");
112-
}
113-
groupsString.append(worldGroup.getName());
114-
}
100+
private String formatStringList(Collection<String> worlds) {
101+
if (worlds.isEmpty()) {
102+
return "&7N/A";
115103
}
116-
issuer.sendInfo(MVInvi18n.INFO_WORLD_INFO, replace("{groups}").with(groupsString));
104+
return StringFormatter.join(worlds, ", ");
117105
}
118106

119107
@Service
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package org.mvplugins.multiverse.inventories.commands;
2+
3+
import com.dumptruckman.minecraft.util.Logging;
4+
import org.bukkit.Bukkit;
5+
import org.bukkit.ChatColor;
6+
import org.bukkit.OfflinePlayer;
7+
import org.bukkit.entity.Player;
8+
import org.bukkit.inventory.Inventory;
9+
import org.jvnet.hk2.annotations.Service;
10+
import org.mvplugins.multiverse.core.command.MVCommandIssuer;
11+
import org.mvplugins.multiverse.core.world.MultiverseWorld;
12+
import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion;
13+
import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission;
14+
import org.mvplugins.multiverse.external.acf.commands.annotation.Description;
15+
import org.mvplugins.multiverse.external.acf.commands.annotation.Flags;
16+
import org.mvplugins.multiverse.external.acf.commands.annotation.Subcommand;
17+
import org.mvplugins.multiverse.external.acf.commands.annotation.Syntax;
18+
import org.mvplugins.multiverse.external.jakarta.inject.Inject;
19+
import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull;
20+
import org.mvplugins.multiverse.inventories.MultiverseInventories;
21+
import org.mvplugins.multiverse.inventories.view.InventoryDataProvider;
22+
import org.mvplugins.multiverse.inventories.view.InventoryGUIHelper;
23+
import org.mvplugins.multiverse.inventories.view.ModifiableInventoryHolder;
24+
import org.mvplugins.multiverse.inventories.view.PlayerInventoryData;
25+
26+
@Service
27+
final class InventoryModifyCommand extends InventoriesCommand {
28+
29+
private final InventoryDataProvider inventoryDataProvider;
30+
private final MultiverseInventories inventories;
31+
private final InventoryGUIHelper inventoryGUIHelper;
32+
33+
@Inject
34+
InventoryModifyCommand(
35+
@NotNull InventoryDataProvider inventoryDataProvider,
36+
@NotNull MultiverseInventories inventories,
37+
@NotNull InventoryGUIHelper inventoryGUIHelper
38+
) {
39+
this.inventoryDataProvider = inventoryDataProvider;
40+
this.inventories = inventories;
41+
this.inventoryGUIHelper = inventoryGUIHelper;
42+
}
43+
44+
// This method contains the logic for the /mvinv modify command
45+
@Subcommand("modify")
46+
@CommandPermission("multiverse.inventories.view.modify") // Specific permission for modification
47+
@CommandCompletion("@mvinvplayernames @mvworlds")
48+
@Syntax("<player> <world>")
49+
@Description("Modify a player's inventory in a specific world.")
50+
void onInventoryModifyCommand(
51+
@NotNull MVCommandIssuer issuer,
52+
53+
// to make sure the command is only run by players
54+
@Flags("resolve=issuerOnly")
55+
@NotNull Player player,
56+
57+
@Syntax("<player>")
58+
@Description("Online or offline player")
59+
OfflinePlayer targetPlayer,
60+
61+
@Syntax("<world>")
62+
@Description("The world the player's inventory is in")
63+
MultiverseWorld world
64+
) {
65+
String worldName = world.getName();
66+
issuer.sendInfo(ChatColor.YELLOW + "Loading inventory data for " + targetPlayer.getName() + "...");
67+
handleInventoryLoadAndDisplay(issuer, player, targetPlayer, worldName);
68+
}
69+
70+
/**
71+
* Handles the asynchronous loading of player inventory data and the display of the GUI.
72+
*
73+
* @param issuer The command issuer.
74+
* @param player The player who will view/modify the inventory.
75+
* @param targetPlayer The offline or online player whose inventory data is being loaded.
76+
* @param worldName The name of the world for which inventory data is loaded.
77+
*/
78+
private void handleInventoryLoadAndDisplay(
79+
@NotNull MVCommandIssuer issuer,
80+
@NotNull Player player,
81+
@NotNull OfflinePlayer targetPlayer,
82+
@NotNull String worldName
83+
) {
84+
inventoryDataProvider.loadPlayerInventoryData(targetPlayer, worldName)
85+
.thenAccept(playerInventoryData -> {
86+
// Ensure GUI operations run on the main thread
87+
Bukkit.getScheduler().runTask(inventories, () -> {
88+
89+
// If the player tries to modify their own live inventory, stop
90+
if (player.getUniqueId().equals(targetPlayer.getUniqueId())
91+
&& player.getWorld().getName().equalsIgnoreCase(worldName)) {
92+
issuer.sendError(ChatColor.RED + "You cannot modify your own live inventory using this command. Use your regular inventory.");
93+
return; // Stop here if it's a live self-inventory
94+
}
95+
createAndOpenGUI(issuer, player, targetPlayer, worldName, playerInventoryData);
96+
});
97+
})
98+
99+
100+
.exceptionally(throwable -> {
101+
// This block runs if an exception occurs during data loading
102+
String errorMessage = throwable.getMessage();
103+
if (errorMessage == null || errorMessage.isEmpty()) {
104+
errorMessage = "An unknown error occurred while loading inventory data.";
105+
}
106+
issuer.sendError(ChatColor.RED + errorMessage);
107+
Logging.fine("Error loading inventory for " + targetPlayer.getName() + ": " + throwable.getMessage());
108+
throwable.printStackTrace();
109+
return null;
110+
});
111+
}
112+
113+
/**
114+
* Creates and opens the custom inventory GUI for modification.
115+
* This method must be called on the main server thread.
116+
*
117+
* @param issuer The command issuer.
118+
* @param player The player who will view/modify the inventory.
119+
* @param targetPlayer The offline player whose inventory is being displayed.
120+
* @param worldName The name of the world for which inventory data is displayed.
121+
* @param playerInventoryData The loaded inventory data.
122+
*/
123+
private void createAndOpenGUI(
124+
@NotNull MVCommandIssuer issuer,
125+
@NotNull Player player,
126+
@NotNull OfflinePlayer targetPlayer,
127+
@NotNull String worldName,
128+
@NotNull PlayerInventoryData playerInventoryData
129+
) {
130+
String title = "Modify " + targetPlayer.getName() + " @ " + worldName;
131+
Inventory inv = Bukkit.createInventory(
132+
new ModifiableInventoryHolder(
133+
targetPlayer,
134+
worldName,
135+
playerInventoryData.profileTypeUsed // Use the determined profile type
136+
),
137+
45, // 5 rows for 36 main + 4 armor + 1 off-hand + 4 fillers
138+
title
139+
);
140+
141+
// Call the helper method to populate the GUI
142+
inventoryGUIHelper.populateInventoryGUI(inv, playerInventoryData, true);
143+
player.openInventory(inv);
144+
issuer.sendInfo(ChatColor.GREEN + playerInventoryData.status.getFormattedMessage(targetPlayer.getName(), worldName) + ". Changes will save on close.");
145+
}
146+
}

0 commit comments

Comments
 (0)