Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ public void loadConfiguration() {
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
setParentOnClaim = getString("regions.set-parent-on-claim", "");
nonplayerBorderBypassOnClaim = getBoolean("regions.nonplayer-border-bypass-on-claim", false);
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);

maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.registry.CustomDomainContext;
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
Expand Down Expand Up @@ -92,8 +95,14 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -131,6 +140,61 @@ public static WorldGuardPlugin inst() {
return inst;
}

@Override
public void onLoad() {
WorldGuard.getInstance().getDomainRegistry().register("nonplayer-protection-domains", n -> new CustomDomain(n) {
private final Set<String> nonplayerProtectionDomains = new HashSet<>();

@Override
public void parseInput(CustomDomainContext context) {
setDirty(true);
nonplayerProtectionDomains.addAll(Arrays.asList(context.getUserInput().split(",")));
}

@Override
public void unmarshal(Object o) {
nonplayerProtectionDomains.clear();
nonplayerProtectionDomains.addAll((Collection<? extends String>) o);
}

@Override
public Object marshal() {
return new ArrayList<>(nonplayerProtectionDomains);
}

@Override
public boolean contains(UUID uniqueId) {
return false;
}

@Override
public boolean contains(String playerName) {
return false;
}

@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return nonplayerProtectionDomains.contains(nonplayerProtectionDomain);
}

@Override
public int size() {
return nonplayerProtectionDomains.size();
}

@Override
public void clear() {
setDirty(true);
nonplayerProtectionDomains.clear();
}

@Override
public String toString() {
return " " + nonplayerProtectionDomains;
}
});
}

/**
* Called on plugin enable.
*/
Expand Down Expand Up @@ -211,6 +275,7 @@ public void onEnable() {
});

((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
((SimpleDomainRegistry) WorldGuard.getInstance().getDomainRegistry()).setInitialized(true);

// Enable metrics
final Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); // bStats plugin id
Expand Down
13 changes: 13 additions & 0 deletions worldguard-core/src/main/java/com/sk89q/worldguard/WorldGuard.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldguard.domains.registry.DomainRegistry;
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.util.profile.cache.HashMapCache;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldguard.util.profile.cache.SQLiteCache;
Expand Down Expand Up @@ -55,6 +57,7 @@ public final class WorldGuard {

private WorldGuardPlatform platform;
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
private final SimpleDomainRegistry domainRegistry = new SimpleDomainRegistry();
private final Supervisor supervisor = new SimpleSupervisor();
private ProfileCache profileCache;
private ProfileService profileService;
Expand Down Expand Up @@ -116,6 +119,16 @@ public FlagRegistry getFlagRegistry() {
return this.flagRegistry;
}


/**
* Get the domain registry.
*
* @return the domain registry
*/
public DomainRegistry getDomainRegistry() {
return this.domainRegistry;
}

/**
* Get the supervisor.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldguard.commands;

import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;

import javax.annotation.Nullable;
import java.util.Map;

public abstract class CommandInputContext<T extends Exception> {
protected final Actor sender;
protected final String input;

protected Map<String, Object> context;

protected CommandInputContext(Actor sender, String input, Map<String, Object> values) {
this.sender = sender;
this.input = input;
this.context = values;
}

public void put(String name, Object value) {
context.put(name, value);
}

public Actor getSender() {
return sender;
}

public String getUserInput() {
return input;
}

/**
* Gets the CommandSender as a player.
*
* @return Player
* @throws InvalidFlagFormat if the sender is not a player
*/
public LocalPlayer getPlayerSender() throws T {
if (sender.isPlayer() && sender instanceof LocalPlayer) {
return (LocalPlayer) sender;
} else {
throw createException("Not a player");
}
}

public Integer getUserInputAsInt() throws T {
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
throw createException("Not a number: " + input);
}
}

public Double getUserInputAsDouble() throws T {
try {
return Double.parseDouble(input);
} catch (NumberFormatException e) {
throw createException("Not a number: " + input);
}
}

protected abstract T createException(String str);

/**
* Get an object from the context by key name.
* May return null if the object does not exist in the context.
*
* @param name key name of the object
* @return the object matching the key, or null
*/
@Nullable
public Object get(String name) {
return get(name, null);
}

/**
* Get an object from the context by key name.
* Will only return null if
* a) you provide null as the default
* b) the key has explicity been set to null
*
* @param name key name of the object
* @return the object matching the key
*/
@Nullable
public Object get(String name, Object defaultValue) {
Object obj;
return (((obj = context.get(name)) != null) || context.containsKey(name)
? obj : defaultValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,27 @@
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.domains.registry.DomainFactory;
import com.sk89q.worldguard.domains.registry.DomainRegistry;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;

public class MemberCommands extends RegionCommandsBase {
Expand Down Expand Up @@ -67,6 +78,8 @@ public void addMember(CommandContext args, Actor sender) throws CommandException
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
resolver.setActor(sender);
resolver.setRegion(region);


final String description = String.format("Adding members to the region '%s' on '%s'", region.getId(), world.getName());
Expand Down Expand Up @@ -101,7 +114,8 @@ public void addOwner(CommandContext args, Actor sender) throws CommandException
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);

resolver.setActor(sender);
resolver.setRegion(region);

final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
Expand Down Expand Up @@ -174,6 +188,8 @@ public void removeMember(CommandContext args, Actor sender) throws CommandExcept
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
resolver.setActor(sender);
resolver.setRegion(region);

callable = resolver;
}
Expand Down Expand Up @@ -217,6 +233,8 @@ public void removeOwner(CommandContext args, Actor sender) throws CommandExcepti
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
resolver.setActor(sender);
resolver.setRegion(region);

callable = resolver;
}
Expand All @@ -229,4 +247,60 @@ public void removeOwner(CommandContext args, Actor sender) throws CommandExcepti
.onFailure("Failed to remove owners", worldGuard.getExceptionConverter())
.buildAndExec(worldGuard.getExecutorService());
}

// TODO: Implement a list for available domains. Maybe /rg domains? or /rg addmembers/addowners/delmembers/delowners?
private static class DomainListBuilder implements Callable<Component> {
private final DomainRegistry domainRegistry;
private final RegionPermissionModel permModel;
private final ProtectedRegion existing;
private final World world;
private final String regionId;
private final Actor sender;
private final boolean isOwner;
private final String domainName;

DomainListBuilder(DomainRegistry domainRegistry, RegionPermissionModel permModel, ProtectedRegion existing,
World world, String regionId, Actor sender, String domainName, boolean isOwner) {
this.domainRegistry = domainRegistry;
this.permModel = permModel;
this.existing = existing;
this.world = world;
this.regionId = regionId;
this.sender = sender;
this.domainName = domainName;
this.isOwner = isOwner;
}

@Override
public Component call() {
ArrayList<String> domainList = new ArrayList<>();

// Need to build a list
for (Map.Entry<String, DomainFactory<?>> domainEntry : domainRegistry.getAll().entrySet()) {
if (!permModel.mayModifyCustomDomain(existing, isOwner, domainEntry.getKey())) {
continue;
}
domainList.add(domainEntry.getKey());
}
Collections.sort(domainList);

final TextComponent.Builder builder = TextComponent.builder("Available domains: ");

final HoverEvent clickToSet = HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set"));
for (int i = 0; i < domainList.size(); i++) {
String domainName = domainList.get(i);

builder.append(TextComponent.of(domainName, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
.hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
"/rg " + (isOwner ? "addowner" : "addmember") +" -w \"" + world.getName() + "\" " + regionId + " " + domainName + ":")));
if (i < domainList.size() + 1) {
builder.append(TextComponent.of(", "));
}
}

return ErrorFormat.wrap("Unknown domain specified: " + domainName)
.append(TextComponent.newline())
.append(builder.build());
}
}
}
Loading