1212import io .papermc .paper .command .brigadier .CommandSourceStack ;
1313import io .papermc .paper .command .brigadier .Commands ;
1414import io .papermc .paper .command .brigadier .argument .ArgumentTypes ;
15+ import org .bukkit .Material ;
1516import org .bukkit .Sound ;
1617import org .bukkit .command .CommandSender ;
1718import 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