@@ -127,7 +127,7 @@ protected void execute(@Nonnull CommandContext ctx,
127127 showHelp (playerData );
128128 break ;
129129 case "admin" :
130- handleAdmin (playerData , args );
130+ handleAdmin (playerData , args , store , playerRef , world );
131131 break ;
132132 default :
133133 playerData .sendMessage (Message .raw ("Unknown subcommand: " + subcommand ).color (RED ));
@@ -136,7 +136,7 @@ protected void execute(@Nonnull CommandContext ctx,
136136 }
137137
138138 // ===== ADMIN =====
139- private void handleAdmin (PlayerRef playerData , String [] args ) {
139+ private void handleAdmin (PlayerRef playerData , String [] args , Store < EntityStore > store , Ref < EntityStore > playerRef , World world ) {
140140 if (!hasAdminPermission (playerData )) {
141141 return ;
142142 }
@@ -161,6 +161,9 @@ private void handleAdmin(PlayerRef playerData, String[] args) {
161161 case "reload" :
162162 handleReload (playerData );
163163 break ;
164+ case "unclaim" :
165+ handleAdminUnclaim (playerData , arg1 , store , playerRef , world );
166+ break ;
164167 default :
165168 playerData .sendMessage (Message .raw ("Unknown admin command: " + adminSubcmd ).color (RED ));
166169 showAdminHelp (playerData );
@@ -172,8 +175,10 @@ private void showAdminHelp(PlayerRef playerData) {
172175 playerData .sendMessage (Message .raw ("/easyclaims admin config - Show current settings" ).color (GRAY ));
173176 playerData .sendMessage (Message .raw ("/easyclaims admin set <key> <value> - Change a setting" ).color (GRAY ));
174177 playerData .sendMessage (Message .raw ("/easyclaims admin reload - Reload config from file" ).color (GRAY ));
178+ playerData .sendMessage (Message .raw ("/easyclaims admin unclaim - Remove claim at your location" ).color (GRAY ));
179+ playerData .sendMessage (Message .raw ("/easyclaims admin unclaim <player> - Remove all claims from player" ).color (GRAY ));
175180 playerData .sendMessage (Message .raw ("" ).color (GRAY ));
176- playerData .sendMessage (Message .raw ("Settings: starting, perhour, max" ).color (AQUA ));
181+ playerData .sendMessage (Message .raw ("Settings: starting, perhour, max, buffer " ).color (AQUA ));
177182 }
178183
179184 // ===== CLAIM =====
@@ -211,6 +216,11 @@ private void handleClaim(PlayerRef playerData, Store<EntityStore> store, Ref<Ent
211216 playerData .sendMessage (Message .raw ("Claim limit reached! (" + currentClaims + "/" + maxClaims + ")" ).color (RED ));
212217 playerData .sendMessage (Message .raw ("Play more to earn additional claims." ).color (GRAY ));
213218 break ;
219+ case TOO_CLOSE_TO_OTHER_CLAIM :
220+ playerData .sendMessage (Message .raw ("Cannot claim here - too close to another player's claim!" ).color (RED ));
221+ int buffer = plugin .getPluginConfig ().getClaimBufferSize ();
222+ playerData .sendMessage (Message .raw ("Claims must be at least " + buffer + " chunks away from other players." ).color (GRAY ));
223+ break ;
214224 }
215225 }
216226
@@ -430,11 +440,15 @@ private void showConfig(PlayerRef playerData) {
430440 playerData .sendMessage (Message .raw ("New players start with: " + config .getStartingClaims () + " claims" ).color (AQUA ));
431441 playerData .sendMessage (Message .raw ("Players earn: " + config .getClaimsPerHour () + " extra claims per hour played" ).color (AQUA ));
432442 playerData .sendMessage (Message .raw ("Maximum claims allowed: " + config .getMaxClaims ()).color (AQUA ));
443+ int buffer = config .getClaimBufferSize ();
444+ String bufferText = buffer > 0 ? buffer + " chunks" : "disabled" ;
445+ playerData .sendMessage (Message .raw ("Claim buffer zone: " + bufferText ).color (AQUA ));
433446 playerData .sendMessage (Message .raw ("" ).color (GRAY ));
434447 playerData .sendMessage (Message .raw ("To change these settings:" ).color (GRAY ));
435448 playerData .sendMessage (Message .raw (" /easyclaims admin set starting <number>" ).color (YELLOW ));
436449 playerData .sendMessage (Message .raw (" /easyclaims admin set perhour <number>" ).color (YELLOW ));
437450 playerData .sendMessage (Message .raw (" /easyclaims admin set max <number>" ).color (YELLOW ));
451+ playerData .sendMessage (Message .raw (" /easyclaims admin set buffer <number>" ).color (YELLOW ));
438452 }
439453
440454 private void handleSet (PlayerRef playerData , String key , String valueStr ) {
@@ -446,6 +460,8 @@ private void handleSet(PlayerRef playerData, String key, String valueStr) {
446460 playerData .sendMessage (Message .raw (" Extra claims earned per hour played" ).color (GRAY ));
447461 playerData .sendMessage (Message .raw (" /easyclaims admin set max <number>" ).color (YELLOW ));
448462 playerData .sendMessage (Message .raw (" Maximum claims any player can have" ).color (GRAY ));
463+ playerData .sendMessage (Message .raw (" /easyclaims admin set buffer <number>" ).color (YELLOW ));
464+ playerData .sendMessage (Message .raw (" Buffer zone in chunks around claims (0 = disabled)" ).color (GRAY ));
449465 return ;
450466 }
451467
@@ -474,8 +490,18 @@ private void handleSet(PlayerRef playerData, String key, String valueStr) {
474490 config .setMaxClaims (value );
475491 playerData .sendMessage (Message .raw ("Maximum claims is now " + value + "!" ).color (GREEN ));
476492 break ;
493+ case "buffer" :
494+ case "buffersize" :
495+ case "claimbuffer" :
496+ config .setClaimBufferSize (value );
497+ if (value == 0 ) {
498+ playerData .sendMessage (Message .raw ("Claim buffer zone disabled!" ).color (GREEN ));
499+ } else {
500+ playerData .sendMessage (Message .raw ("Claim buffer zone set to " + value + " chunks!" ).color (GREEN ));
501+ }
502+ break ;
477503 default :
478- playerData .sendMessage (Message .raw ("Unknown setting! Try: starting, perhour, or max " ).color (RED ));
504+ playerData .sendMessage (Message .raw ("Unknown setting! Try: starting, perhour, max, or buffer " ).color (RED ));
479505 }
480506 }
481507
@@ -484,4 +510,58 @@ private void handleReload(PlayerRef playerData) {
484510 playerData .sendMessage (Message .raw ("Configuration reloaded!" ).color (GREEN ));
485511 showConfig (playerData );
486512 }
513+
514+ // ===== ADMIN: UNCLAIM =====
515+ private void handleAdminUnclaim (PlayerRef playerData , String playerInput , Store <EntityStore > store , Ref <EntityStore > playerRef , World world ) {
516+ if (playerInput == null || playerInput .isEmpty ()) {
517+ // Unclaim chunk at current location
518+ TransformComponent transform = store .getComponent (playerRef , TransformComponent .getComponentType ());
519+ Vector3d position = transform .getPosition ();
520+ String worldName = world .getName ();
521+
522+ int chunkX = ChunkUtil .chunkCoordinate ((int ) position .getX ());
523+ int chunkZ = ChunkUtil .chunkCoordinate ((int ) position .getZ ());
524+
525+ UUID owner = plugin .getClaimStorage ().getClaimOwner (worldName , chunkX , chunkZ );
526+ if (owner == null ) {
527+ playerData .sendMessage (Message .raw ("This chunk is not claimed." ).color (YELLOW ));
528+ return ;
529+ }
530+
531+ String ownerName = plugin .getClaimStorage ().getPlayerName (owner );
532+ plugin .getClaimStorage ().removeClaim (owner , worldName , chunkX , chunkZ );
533+ playerData .sendMessage (Message .raw ("Removed claim [" + chunkX + ", " + chunkZ + "] from " + ownerName ).color (GREEN ));
534+ plugin .refreshWorldMapChunk (worldName , chunkX , chunkZ );
535+ } else {
536+ // Unclaim all chunks from a specific player
537+ UUID targetId = null ;
538+ String targetName = playerInput ;
539+
540+ // Try online player first
541+ PlayerRef targetPlayer = Universe .get ().getPlayerByUsername (playerInput , NameMatching .EXACT_IGNORE_CASE );
542+ if (targetPlayer != null ) {
543+ targetId = targetPlayer .getUuid ();
544+ targetName = targetPlayer .getUsername ();
545+ } else {
546+ // Try UUID
547+ try {
548+ targetId = UUID .fromString (playerInput );
549+ targetName = plugin .getClaimStorage ().getPlayerName (targetId );
550+ } catch (IllegalArgumentException e ) {
551+ playerData .sendMessage (Message .raw ("Player not found: " + playerInput ).color (RED ));
552+ return ;
553+ }
554+ }
555+
556+ int count = plugin .getClaimManager ().unclaimAll (targetId );
557+ if (count > 0 ) {
558+ playerData .sendMessage (Message .raw ("Removed " + count + " claim(s) from " + targetName ).color (GREEN ));
559+ for (String worldName : EasyClaims .WORLDS .keySet ()) {
560+ plugin .refreshWorldMap (worldName );
561+ }
562+ } else {
563+ playerData .sendMessage (Message .raw (targetName + " doesn't have any claims." ).color (YELLOW ));
564+ }
565+ }
566+ }
487567}
0 commit comments