Skip to content

Commit cc68e45

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents 5520f38 + c497efa commit cc68e45

19 files changed

Lines changed: 975 additions & 21 deletions

File tree

core/src/main/java/github/nighter/smartspawner/SmartSpawner.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import github.nighter.smartspawner.commands.list.gui.adminstacker.AdminStackerHandler;
1212
import github.nighter.smartspawner.commands.prices.PricesGUI;
1313
import github.nighter.smartspawner.spawner.config.SpawnerSettingsConfig;
14+
import github.nighter.smartspawner.spawner.config.ItemSpawnerSettingsConfig;
1415
import github.nighter.smartspawner.logging.LoggingConfig;
1516
import github.nighter.smartspawner.logging.SpawnerActionLogger;
1617
import github.nighter.smartspawner.logging.SpawnerAuditListener;
@@ -80,6 +81,7 @@ public class SmartSpawner extends JavaPlugin implements SmartSpawnerPlugin {
8081
private LanguageUpdater languageUpdater;
8182
private MessageService messageService;
8283
private SpawnerSettingsConfig spawnerSettingsConfig;
84+
private ItemSpawnerSettingsConfig itemSpawnerSettingsConfig;
8385

8486
// Factories
8587
private SpawnerItemFactory spawnerItemFactory;
@@ -229,6 +231,7 @@ private void initializeServices() {
229231

230232
// Initialize new unified spawner settings config (but don't load yet)
231233
this.spawnerSettingsConfig = new SpawnerSettingsConfig(this);
234+
this.itemSpawnerSettingsConfig = new ItemSpawnerSettingsConfig(this);
232235

233236
// Initialize logging system
234237
this.loggingConfig = new LoggingConfig(this);
@@ -246,6 +249,11 @@ private void initializeEconomyComponents() {
246249
spawnerSettingsConfig.load();
247250
}
248251

252+
// Load item spawner settings
253+
if (itemSpawnerSettingsConfig != null) {
254+
itemSpawnerSettingsConfig.load();
255+
}
256+
249257
// Pre-warm the head texture cache after settings are loaded
250258
// This prevents the brief flash of default player heads when opening GUIs
251259
SpawnerMobHeadTexture.prewarmCache();
@@ -405,6 +413,11 @@ public void reload() {
405413
SpawnerMobHeadTexture.clearCache();
406414
}
407415

416+
// Reload item spawner settings config
417+
if (itemSpawnerSettingsConfig != null) {
418+
itemSpawnerSettingsConfig.reload();
419+
}
420+
408421
// Reload logging system
409422
loggingConfig.loadConfig();
410423
spawnerActionLogger.shutdown();

core/src/main/java/github/nighter/smartspawner/commands/give/GiveSubCommand.java

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.papermc.paper.command.brigadier.CommandSourceStack;
1313
import io.papermc.paper.command.brigadier.Commands;
1414
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
15+
import org.bukkit.Material;
1516
import org.bukkit.Sound;
1617
import org.bukkit.command.CommandSender;
1718
import org.bukkit.entity.EntityType;
@@ -59,9 +60,10 @@ public LiteralArgumentBuilder<CommandSourceStack> build() {
5960
LiteralArgumentBuilder<CommandSourceStack> builder = Commands.literal(getName());
6061
builder.requires(source -> hasPermission(source.getSender()));
6162

62-
// Add subcommands for regular and vanilla spawners
63+
// Add subcommands for regular, vanilla, and item spawners
6364
builder.then(buildRegularGiveCommand());
6465
builder.then(buildVanillaGiveCommand());
66+
builder.then(buildItemSpawnerGiveCommand());
6567

6668
return builder;
6769
}
@@ -88,6 +90,17 @@ private LiteralArgumentBuilder<CommandSourceStack> buildVanillaGiveCommand() {
8890
IntegerArgumentType.getInteger(context, "amount"))))));
8991
}
9092

93+
private LiteralArgumentBuilder<CommandSourceStack> buildItemSpawnerGiveCommand() {
94+
return Commands.literal("item_spawner")
95+
.then(Commands.argument("player", ArgumentTypes.player())
96+
.then(Commands.argument("itemType", StringArgumentType.word())
97+
.suggests(createItemSuggestions())
98+
.executes(context -> executeGiveItemSpawner(context, 1))
99+
.then(Commands.argument("amount", IntegerArgumentType.integer(1, MAX_AMOUNT))
100+
.executes(context -> executeGiveItemSpawner(context,
101+
IntegerArgumentType.getInteger(context, "amount"))))));
102+
}
103+
91104
private SuggestionProvider<CommandSourceStack> createMobSuggestions() {
92105
return (context, builder) -> {
93106
String input = builder.getRemaining().toLowerCase();
@@ -99,6 +112,17 @@ private SuggestionProvider<CommandSourceStack> createMobSuggestions() {
99112
};
100113
}
101114

115+
private SuggestionProvider<CommandSourceStack> createItemSuggestions() {
116+
return (context, builder) -> {
117+
String input = builder.getRemaining().toLowerCase();
118+
plugin.getItemSpawnerSettingsConfig().getValidItemSpawnerMaterials().stream()
119+
.map(material -> material.name().toLowerCase())
120+
.filter(item -> item.startsWith(input))
121+
.forEach(builder::suggest);
122+
return builder.buildFuture();
123+
};
124+
}
125+
102126
@Override
103127
public int execute(CommandContext<CommandSourceStack> context) {
104128
return 0;
@@ -179,4 +203,81 @@ private int executeGive(CommandContext<CommandSourceStack> context, boolean isVa
179203
return 0;
180204
}
181205
}
206+
207+
private int executeGiveItemSpawner(CommandContext<CommandSourceStack> context, int amount) {
208+
CommandSender sender = context.getSource().getSender();
209+
210+
// Log command execution
211+
logCommandExecution(context);
212+
213+
try {
214+
// Get the player selector and resolve it
215+
var playerSelector = context.getArgument("player", io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver.class);
216+
List<Player> players = playerSelector.resolve(context.getSource());
217+
218+
if (players.isEmpty()) {
219+
plugin.getMessageService().sendMessage(sender, "command_give_player_not_found");
220+
return 0;
221+
}
222+
223+
Player target = players.get(0);
224+
String itemType = StringArgumentType.getString(context, "itemType");
225+
226+
// Validate item type
227+
Material itemMaterial;
228+
try {
229+
itemMaterial = Material.valueOf(itemType.toUpperCase());
230+
} catch (IllegalArgumentException e) {
231+
plugin.getMessageService().sendMessage(sender, "command_give_invalid_item_type");
232+
return 0;
233+
}
234+
235+
// Verify it's a valid item spawner type
236+
if (!plugin.getItemSpawnerSettingsConfig().isValidItemSpawner(itemMaterial)) {
237+
plugin.getMessageService().sendMessage(sender, "command_give_invalid_item_spawner");
238+
return 0;
239+
}
240+
241+
// Create item spawner
242+
ItemStack spawnerItem = spawnerItemFactory.createItemSpawnerItem(itemMaterial, amount);
243+
244+
// Give the item to the player
245+
if (target.getInventory().firstEmpty() == -1) {
246+
target.getWorld().dropItem(target.getLocation(), spawnerItem);
247+
plugin.getMessageService().sendMessage(target, "command_give_inventory_full");
248+
} else {
249+
target.getInventory().addItem(spawnerItem);
250+
}
251+
252+
// Play sound
253+
target.playSound(target.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1.0f, 1.0f);
254+
255+
// Get formatted item names for placeholders
256+
String itemName = plugin.getLanguageManager().getVanillaItemName(itemMaterial);
257+
String smallCapsItemName = plugin.getLanguageManager().getSmallCaps(itemName);
258+
259+
// Create placeholders for sender message (use "entity" key for compatibility with spawner messages)
260+
HashMap<String, String> senderPlaceholders = new HashMap<>();
261+
senderPlaceholders.put("player", target.getName());
262+
senderPlaceholders.put("entity", itemName);
263+
senderPlaceholders.put("ᴇɴᴛɪᴛʏ", smallCapsItemName);
264+
senderPlaceholders.put("amount", String.valueOf(amount));
265+
266+
// Create placeholders for target message
267+
HashMap<String, String> targetPlaceholders = new HashMap<>();
268+
targetPlaceholders.put("amount", String.valueOf(amount));
269+
targetPlaceholders.put("entity", itemName);
270+
targetPlaceholders.put("ᴇɴᴛɪᴛʏ", smallCapsItemName);
271+
272+
// Send messages with placeholders (use same keys as regular spawners)
273+
String messageKey = "command_give_spawner_";
274+
plugin.getMessageService().sendMessage(sender, messageKey + "given", senderPlaceholders);
275+
plugin.getMessageService().sendMessage(target, messageKey + "received", targetPlaceholders);
276+
277+
return 1;
278+
} catch (Exception e) {
279+
plugin.getLogger().severe("Error executing give item spawner command: " + e.getMessage());
280+
return 0;
281+
}
282+
}
182283
}

0 commit comments

Comments
 (0)