diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/index/HashMapIndex.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/index/HashMapIndex.java index 61e0f1e2..c9a49658 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/index/HashMapIndex.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/index/HashMapIndex.java @@ -24,9 +24,11 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.protection.managers.RegionDifference; import com.sk89q.worldguard.protection.managers.RemovalStrategy; import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; import javax.annotation.Nullable; import java.util.Collection; @@ -38,6 +40,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Function; import java.util.function.Predicate; +import java.util.logging.Level; /** * An index that stores regions in a hash map, which allows for fast lookup @@ -74,9 +77,13 @@ private void performAdd(ProtectedRegion region) { ProtectedRegion existing = regions.get(normalId); - // Casing / form of ID has changed - if (existing != null && !existing.getId().equals(region.getId())) { - removed.add(existing); + if (existing != null) { + removeAndReplaceParents(existing.getId(), RemovalStrategy.UNSET_PARENT_IN_CHILDREN, region, false); + + // Casing / form of ID has not changed + if (existing.getId().equals(region.getId())) { + removed.remove(existing); + } } regions.put(normalId, region); @@ -134,6 +141,10 @@ public void add(ProtectedRegion region) { @Override public Set remove(String id, RemovalStrategy strategy) { + return removeAndReplaceParents(id, strategy, null, true); + } + + private Set removeAndReplaceParents(String id, RemovalStrategy strategy, @Nullable ProtectedRegion replacement, boolean rebuildIndex) { checkNotNull(id); checkNotNull(strategy); @@ -161,7 +172,12 @@ public Set remove(String id, RemovalStrategy strategy) { it.remove(); break; case UNSET_PARENT_IN_CHILDREN: - current.clearParent(); + try { + current.setParent(replacement); + } catch (CircularInheritanceException e) { + WorldGuard.logger.log(Level.WARNING, "Failed to replace parent '" + parent.getId() + "' of child '" + current.getId() + "' with replacement '" + replacement.getId() + "'", e); + current.clearParent(); + } } } } @@ -174,7 +190,9 @@ public Set remove(String id, RemovalStrategy strategy) { this.removed.addAll(removedSet); - rebuildIndex(); + if (rebuildIndex) { + rebuildIndex(); + } } return removedSet;