Add sponge support.

This commit is contained in:
bloodshot 2019-11-24 17:01:05 -05:00
parent 8b4239452d
commit 557f09a4de
278 changed files with 49238 additions and 0 deletions

View File

@ -1,2 +1,3 @@
include "bukkit"
include "sponge"
include "GriefDefenderAPI"

203
sponge/build.gradle Normal file
View File

@ -0,0 +1,203 @@
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
url = 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
}
}
plugins {
id 'com.github.johnrengelman.shadow' version '5.1.0'
id 'org.spongepowered.plugin' version '0.8.1'
id 'net.minecrell.vanillagradle.server' version '2.2-4'
id 'java'
}
compileJava.options.encoding = 'UTF-8'
// Environment variables for the build set by the build server
ext.buildNumber = System.env.BUILD_NUMBER ?: '0'
defaultTasks 'clean', 'build'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
archivesBaseName = project.name.toLowerCase()
project.ext.getGitHash = {
def command = Runtime.getRuntime().exec("git rev-parse --short HEAD")
def result = command.waitFor()
return (result == 0) ? command.inputStream.text.trim() : "nogit"
}
repositories {
mavenLocal()
maven {
name = 'sk89q'
url = 'https://maven.sk89q.com/repo'
}
maven {
name = 'bstats'
url = 'https://repo.codemc.org/repository/maven-public'
}
maven {
name = 'sponge'
url = 'https://repo.spongepowered.org/maven/'
}
maven {
name = 'nucleus'
url = 'http://repo.drnaylor.co.uk/artifactory/list/minecraft'
}
maven {
name = 'sonatype_releases'
url = 'https://oss.sonatype.org/content/repositories/releases'
}
maven {
name = 'sonatype_snapshots'
url = 'https://oss.sonatype.org/content/repositories/snapshots'
}
maven {
name = 'glare'
url = 'https://repo.glaremasters.me/repository/bloodshot'
}
maven {
name = 'aikar'
url = 'https://repo.aikar.co/content/groups/aikar'
}
maven {
name = 'worldedit'
url = 'http://maven.sk89q.com/artifactory/repo'
}
maven {
name = 'jitpack'
url = 'https://jitpack.io'
}
}
minecraft {
version = project.minecraftVersion
mappings = project.mcpMappings
}
sourceSets {
api
}
dependencies {
compileOnly 'com.griefdefender:api:1.0.0-20190906.173641-10'
compileOnly "com.griefdefender:reflect-helper:1.0"
// Sponge
apiCompile "org.spongepowered:spongeapi:$apiVersion"
compileOnly ("org.spongepowered:spongecommon:$commonVersion:dev") {
exclude module: 'testplugins'
}
// Plugins
compileOnly ("io.github.nucleuspowered:nucleus-api:1.14.1-S7.1"){
exclude module: 'spongeapi'
}
compile "com.github.bloodmc:mcclans-api:develop-SNAPSHOT"
compileOnly "com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT"
// required for bootstrap
compile "com.googlecode.json-simple:json-simple:1.1.1"
compileOnly "aopalliance:aopalliance:1.0"
compileOnly "co.aikar:acf-core:0.5.0-SNAPSHOT"
compileOnly "co.aikar:acf-sponge:0.5.0-SNAPSHOT"
compileOnly "co.aikar:locales:1.0-SNAPSHOT"
compileOnly "co.aikar:minecraft-timings:1.0.4"
compileOnly "co.aikar:Table:1.0.0-SNAPSHOT"
compileOnly "com.flowpowered:flow-math:1.0.3"
compileOnly "com.github.ben-manes.caffeine:caffeine:2.7.0"
compileOnly "com.squareup.okhttp3:okhttp:3.14.2"
compileOnly "com.squareup.okio:okio:2.2.2"
compileOnly "commons-io:commons-io:2.6"
compileOnly "it.unimi.dsi:fastutil:8.2.3"
compileOnly "javax.inject:javax.inject:1"
compileOnly "me.lucko:jar-relocator:1.3"
compileOnly "me.lucko.luckperms:luckperms-api:4.4"
compileOnly "net.jodah:expiringmap:0.5.9"
compileOnly "org.apache.commons:commons-lang3:3.9"
compileOnly "org.checkerframework:checker:2.8.2"
compileOnly "org.jetbrains:annotations:17.0.0"
compileOnly "org.jetbrains.kotlin:kotlin-stdlib:1.3.31"
compileOnly "org.ow2.asm:asm-debug-all:5.2"
compileOnly "org.spongepowered:configurate-core:3.7-SNAPSHOT"
compileOnly "org.spongepowered:configurate-gson:3.7-SNAPSHOT"
compileOnly "org.spongepowered:configurate-hocon:3.7-SNAPSHOT"
compileOnly "org.spongepowered:configurate-yaml:3.7-SNAPSHOT"
compileOnly "net.kyori:event-api:3.0.0"
compileOnly "net.kyori:event-method:3.0.0"
compileOnly "net.kyori:event-method-asm:3.0.0"
compileOnly "net.kyori:text-adapter-bukkit:3.0.3"
compileOnly "net.kyori:text-adapter-bungeecord:3.0.3"
compileOnly "net.kyori:text-adapter-spongeapi:3.0.3"
compileOnly "net.kyori:text-api:3.0.2"
compileOnly "net.kyori:text-serializer-gson:3.0.2"
compileOnly "net.kyori:text-serializer-legacy:3.0.2"
compileOnly "net.kyori:text-serializer-plain:3.0.2"
}
jar {
manifest.attributes('FMLAT': 'griefdefender_at.cfg')
manifest.attributes('Implementation-Title': 'GriefDefender')
manifest.attributes('Implementation-Version': "$version")
manifest.attributes('Git-Hash': project.ext.getGitHash())
classifier = 'SNAPSHOT'
baseName = 'griefdefender-sponge'
}
if (JavaVersion.current().isJava8Compatible()) {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives shadowJar
}
shadowJar {
mainSpec.sourcePaths.clear()
dependsOn reobfJar
classifier = ''
dependencies {
include dependency("com.squareup.okhttp3:okhttp:3.9.1")
include dependency("com.squareup.okio:okio:1.13.0")
include dependency("com.googlecode.json-simple:json-simple:1.1.1")
}
relocate("aopalliance", "com.griefdefender.lib.aopalliance")
relocate("com.github.benmanes.caffeine", "com.griefdefender.lib.caffeine")
relocate("it.unimi.dsi", "com.griefdefender.lib.fastutil")
relocate("net.jodah", "com.griefdefender.lib.jodah")
relocate("okhttp3", "com.griefdefender.lib.okhttp3")
relocate("okio", "com.griefdefender.lib.okio")
relocate("org.apache.commons.io", "com.griefdefender.lib.commonsio")
relocate("org.apache.commons.lang3", "com.griefdefender.lib.commonslang3")
relocate("org.checkerframework", "com.griefdefender.lib.checkerframework")
relocate("org.jetbrains", "com.griefdefender.lib.jetbrains")
exclude "dummyThing"
afterEvaluate {
from zipTree(reobfJar.jar)
}
}

11
sponge/gradle.properties Normal file
View File

@ -0,0 +1,11 @@
name=GriefDefender
group=com.griefdefender
url=https://github.com/bloodmc/GriefDefender
version=1.2.2
apiVersion=7.2.0-SNAPSHOT
commonVersion=1.12.2-7.1.7-SNAPSHOT
minecraftVersion=1.12.2
mcpMappings=snapshot_20180808
org.gradle.jvmargs=-Xmx3G

View File

@ -0,0 +1,228 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.inject.Inject;
import com.griefdefender.util.BootstrapUtil;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.spongepowered.api.MinecraftVersion;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@Plugin(id = "griefdefender", name = "GriefDefender", version = "1.0.0", description = "Designed to defend world from all types of grief.")
public class GDBootstrap {
@Inject public PluginContainer pluginContainer;
@Inject private Logger logger;
@Inject @ConfigDir(sharedRoot = false)
private Path configPath;
private Map<String, File> jarMap = new HashMap<>();
private List<String> relocateList = new ArrayList<>();
private static GDBootstrap instance;
private static final String LIB_ROOT_PATH = "./config/griefdefender/lib/";
private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7";
public static GDBootstrap getInstance() {
return instance;
}
@Listener(order = Order.LAST)
public void onPreInit(GamePreInitializationEvent event) {
instance = this;
final JSONParser parser = new JSONParser();
String bukkitJsonVersion = null;
this.getLogger().info("Loading libraries...");
final MinecraftVersion version = Sponge.getPlatform().getMinecraftVersion();
if (Sponge.getPlatform().getMinecraftVersion().getName().contains("1.12.2")) {
bukkitJsonVersion = "1.12.2";
} else {
this.getLogger().error("Detected unsupported version '" + version.getName() + "'. GriefDefender only 1.12.2. GriefDefender will NOT load.");
return;
}
try {
final InputStream in = getClass().getResourceAsStream("/" + bukkitJsonVersion + ".json");
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
final JSONObject a = (JSONObject) parser.parse(reader);
final JSONArray libraries = (JSONArray) a.get("libraries");
if (libraries == null) {
this.getLogger().error("Resource " + bukkitJsonVersion + ".json is corrupted!. Please contact author for assistance.");
return;
}
final Iterator<JSONObject> iterator = libraries.iterator();
while (iterator.hasNext()) {
JSONObject lib = iterator.next();
final String name = (String) lib.get("name");
final String sha1 = (String) lib.get("sha1");
final String path = (String) lib.get("path");
final String relocate = (String) lib.get("relocate");
final String url = (String) lib.get("url");
final Path libPath = Paths.get(LIB_ROOT_PATH).resolve(path);
final File file = libPath.toFile();
downloadLibrary(name, relocate, sha1, url, libPath);
}
} catch (Throwable t) {
t.printStackTrace();
}
// Inject jar-relocator and asm debug
injectRelocatorDeps();
// Relocate all GD dependencies and inject
GDRelocator.getInstance().relocateJars(this.jarMap);
// Boot GD
GriefDefenderPlugin.getInstance().onPreInit(event, this.logger, this.configPath, this.pluginContainer);
//Sponge.getEventManager().registerListeners(GriefDefenderPlugin.getInstance(), GriefDefenderPlugin.getInstance());
}
public List<String> getRelocateList() {
return this.relocateList;
}
private void injectRelocatorDeps() {
String name = "org.ow2.asm:asm-debug-all:5.2";
File file = this.jarMap.get(name);
BootstrapUtil.addUrlToClassLoader(name, file);
name = "me.lucko:jar-relocator:1.3";
file = this.jarMap.get(name);
BootstrapUtil.addUrlToClassLoader(name, file);
// inject reflect helper
final String javaVersion = System.getProperty("java.version");
if (getJavaVersion() >= 11) {
name = "com.griefdefender:reflect-helper:2.0";
} else {
name = "com.griefdefender:reflect-helper:1.0";
}
file = this.jarMap.get(name);
BootstrapUtil.addUrlToClassLoader(name, file);
}
public void downloadLibrary(String name, String relocate, String sha1, String url, Path libPath) {
final File file = libPath.toFile();
this.jarMap.put(name, file);
if (relocate != null && !relocate.isEmpty() && relocate.contains(":")) {
this.relocateList.add(relocate);
}
if (!Files.exists(libPath)) {
this.getLogger().info("Downloading library " + name + " ...");
try {
URL website = new URL(url);
URLConnection urlConnection = website.openConnection();
// Some maven repos like nexus require a user agent so we just pass one to satisfy it
urlConnection.setRequestProperty("User-Agent", USER_AGENT);
ReadableByteChannel rbc = Channels.newChannel(urlConnection.getInputStream());
if (!Files.exists(libPath)) {
file.getParentFile().mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
} catch (IOException e) {
this.getLogger().error("An error occured while downloading library '" + name + "'. Skipping...");
e.printStackTrace();
return;
}
final String hash = getLibraryHash(file);
if (hash == null || !sha1.equals(hash)) {
this.getLogger().error("Detected invalid hash '" + hash + "' for file '" + libPath + "'. Expected '" + sha1 + "'. Skipping...");
try {
Files.delete(libPath);
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
this.jarMap.put(name, file);
}
private String getLibraryHash(File file) {
try {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
final byte[] data = Files.readAllBytes(file.toPath());
final byte[] b = md.digest(data);
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < b.length; i++) {
if ((0xff & b[i]) < 0x10) {
buffer.append("0" + Integer.toHexString((0xFF & b[i])));
} else {
buffer.append(Integer.toHexString(0xFF & b[i]));
}
}
return buffer.toString();
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public Logger getLogger() {
return this.logger;
}
private static int getJavaVersion() {
String version = System.getProperty("java.version");
if(version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
final int dot = version.indexOf(".");
if(dot != -1) {
version = version.substring(0, dot);
}
}
return Integer.parseInt(version);
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import static com.google.common.base.Preconditions.checkNotNull;
import com.griefdefender.api.CatalogType;
import java.util.StringJoiner;
public abstract class GDCatalogType implements CatalogType {
private final String id;
public GDCatalogType(String id) {
this.id = checkNotNull(id, "id");
}
@Override
public final String getId() {
return this.id;
}
@Override
public String getName() {
return getId();
}
@Override
public final int hashCode() {
return this.id.hashCode();
}
@Override
public final boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CatalogType other = (CatalogType) obj;
return getId().equals(other.getId());
}
@Override
public String toString() {
return new StringJoiner(", ", GDCatalogType.class.getSimpleName() + "[", "]")
.add("id=" + getId())
.add("name=" + getName())
.toString();
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.griefdefender.api.ChatType;
public class GDChatType implements ChatType {
private final String id;
private final String name;
public GDChatType(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
}

View File

@ -0,0 +1,109 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.common.collect.ImmutableList;
import com.google.inject.Singleton;
import com.griefdefender.api.Core;
import com.griefdefender.api.Group;
import com.griefdefender.api.Subject;
import com.griefdefender.api.User;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.api.claim.ClaimManager;
import com.griefdefender.api.data.PlayerData;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.cache.PermissionHolderCache;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Singleton
public class GDCore implements Core {
@Override
public boolean isEnabled(UUID worldUniqueId) {
return GriefDefenderPlugin.getInstance().claimsEnabledForWorld(worldUniqueId);
}
@Override
public ClaimBlockSystem getClaimBlockSystem() {
return GriefDefenderPlugin.getGlobalConfig().getConfig().playerdata.claimBlockSystem;
}
@Override
public boolean isEconomyModeEnabled() {
return GriefDefenderPlugin.getInstance().isEconomyModeEnabled();
}
@Override
public boolean isProtectionModuleEnabled(Flag flag) {
return GriefDefenderPlugin.getGlobalConfig().getConfig().modules.isProtectionModuleEnabled(flag.toString());
}
@Override
public ClaimManager getClaimManager(UUID worldUniqueId) {
return GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(worldUniqueId);
}
@Override
public Optional<PlayerData> getPlayerData(UUID worldUniqueId, UUID playerUniqueId) {
return Optional.ofNullable(GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(worldUniqueId, playerUniqueId));
}
@Override
public List<Claim> getAllPlayerClaims(UUID playerUniqueId) {
List<Claim> claimList = new ArrayList<>();
for (World world : Sponge.getServer().getWorlds()) {
claimList.addAll(this.getClaimManager(world.getUniqueId()).getPlayerClaims(playerUniqueId));
}
return ImmutableList.copyOf(claimList);
}
@Override
public Subject getDefaultSubject() {
return GriefDefenderPlugin.DEFAULT_HOLDER;
}
@Override
public Subject getSubject(String identifier) {
return PermissionHolderCache.getInstance().getOrCreateHolder(identifier);
}
@Override
public User getUser(UUID uuid) {
return PermissionHolderCache.getInstance().getOrCreateUser(uuid);
}
@Override
public Group getGroup(String name) {
return PermissionHolderCache.getInstance().getOrCreateGroup(name);
}
}

View File

@ -0,0 +1,224 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.griefdefender.api.Tristate;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.util.HttpClient;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.plugin.PluginContainer;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.GZIPOutputStream;
public class GDDebugData {
private static final String BYTEBIN_ENDPOINT = "https://bytebin.lucko.me/post";
private static final String DEBUG_VIEWER_URL = "https://griefdefender.github.io/debug/?";
private static final MediaType PLAIN_TYPE = MediaType.parse("text/plain; charset=utf-8");
private static final int MAX_LINES = 5000;
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private static final Component GD_TEXT = TextComponent.builder("").append("[", TextColor.WHITE).append("GD", TextColor.AQUA).append("] ", TextColor.WHITE).build();
private final CommandSource source;
private final List<String> header;
private final List<String> records;
private final long startTime = System.currentTimeMillis();
private boolean verbose;
private User target;
public GDDebugData(CommandSource source, User target, boolean verbose) {
this.source = source;
this.target = target;
this.verbose = verbose;
this.records = new ArrayList<>();
this.header = new ArrayList<>();
this.header.add("# GriefDefender Debug Log");
this.header.add("#### This file was automatically generated by [GriefDefender](https://github.com/bloodmc/GriefDefender) ");
this.header.add("");
this.header.add("### Metadata");
this.header.add("| Key | Value |");
this.header.add("|-----|-------|");
this.header.add("| GD Version | " + GriefDefenderPlugin.IMPLEMENTATION_VERSION + "|");
this.header.add("| Sponge Version | " + GriefDefenderPlugin.SPONGE_VERSION + "|");
final PluginContainer lpContainer = Sponge.getPluginManager().getPlugin("luckperms").orElse(null);
if (lpContainer != null) {
final String version = lpContainer.getVersion().orElse(null);
if (version != null) {
this.header.add("| LuckPerms Version | " + version);
}
}
this.header.add("| " + PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_USER) + " | " + (this.target == null ? "ALL" : this.target.getName()) + "|");
this.header.add("| " + PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().DEBUG_RECORD_START) + " | " + DATE_FORMAT.format(new Date(this.startTime)) + "|");
}
public void addRecord(String flag, String trust, String source, String target, String location, String user, String permission, Tristate result) {
if (this.records.size() < MAX_LINES) {
this.records.add("| " + flag + " | " + trust + " | " + source + " | " + target + " | " + location + " | " + user + " | " + permission + " | " + result + " | ");
} else {
TextAdapter.sendComponent(this.source, TextComponent.builder("").append("MAX DEBUG LIMIT REACHED!").append("\n")
.append("Pasting output...", TextColor.GREEN).build());
this.pasteRecords();
this.records.clear();
GriefDefenderPlugin.debugActive = false;
TextAdapter.sendComponent(this.source, TextComponent.builder("").append(GD_TEXT).append("Debug ", TextColor.GRAY).append("OFF", TextColor.RED).build());
}
}
public CommandSource getSource() {
return this.source;
}
public User getTarget() {
return this.target;
}
public boolean isRecording() {
return !this.verbose;
}
public void setTarget(User user) {
this.target = user;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
public void pasteRecords() {
if (this.records.isEmpty()) {
TextAdapter.sendComponent(this.source, MessageCache.getInstance().DEBUG_NO_RECORDS);
return;
}
final long endTime = System.currentTimeMillis();
List<String> debugOutput = new ArrayList<>(this.header);
final String RECORD_END = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().DEBUG_RECORD_END);
final String TIME_ELAPSED = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().DEBUG_TIME_ELAPSED);
final String OUTPUT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_OUTPUT);
final String FLAG = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_FLAG);
final String TRUST = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_TRUST);
final String LOCATION = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_LOCATION);
final String SOURCE = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_SOURCE);
final String TARGET = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_TARGET);
final String USER = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_USER);
final String PERMISSION = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_PERMISSION);
final String RESULT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_RESULT);
debugOutput.add("| " + RECORD_END + " | " + DATE_FORMAT.format(new Date(endTime)) + "|");
long elapsed = (endTime - startTime) / 1000L;
debugOutput.add("| " + TIME_ELAPSED + " | " + elapsed + " seconds" + "|");
debugOutput.add("");
debugOutput.add("### " + OUTPUT) ;
debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + " | " + PERMISSION + " | " + RESULT + " |");
debugOutput.add("|------|-------|--------|--------|----------|------|------------|--------|");
debugOutput.addAll(this.records);
String content = String.join("\n", debugOutput);
String pasteId;
try {
pasteId = postContent(content);
} catch (Exception e) {
TextAdapter.sendComponent(this.source, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DEBUG_ERROR_UPLOAD,
ImmutableMap.of("content", TextComponent.of(e.getMessage(), TextColor.WHITE))));
return;
}
String url = DEBUG_VIEWER_URL + pasteId;
URL jUrl;
try {
jUrl = new URL(url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
TextAdapter.sendComponent(this.source, TextComponent.builder()
.append(MessageCache.getInstance().DEBUG_PASTE_SUCCESS)
.append(" : " + url, TextColor.GREEN)
.clickEvent(ClickEvent.openUrl(jUrl.toString())).build());
}
private static String postContent(String content) throws IOException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
try (GZIPOutputStream writer = new GZIPOutputStream(byteOut)) {
writer.write(content.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
RequestBody body = RequestBody.create(PLAIN_TYPE, byteOut.toByteArray());
Request.Builder requestBuilder = new Request.Builder()
.url(BYTEBIN_ENDPOINT)
.header("Content-Encoding", "gzip")
.post(body);
Request request = requestBuilder.build();
try (Response response = HttpClient.makeCall(request)) {
try (ResponseBody responseBody = response.body()) {
if (responseBody == null) {
throw new RuntimeException("No response");
}
try (InputStream inputStream = responseBody.byteStream()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
JsonObject object = new Gson().fromJson(reader, JsonObject.class);
return object.get("key").getAsString();
}
}
}
}
}
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.inject.Singleton;
import com.griefdefender.api.event.Event;
import com.griefdefender.api.event.EventManager;
import net.kyori.event.EventBus;
import net.kyori.event.SimpleEventBus;
import net.kyori.event.method.MethodSubscriptionAdapter;
import net.kyori.event.method.SimpleMethodSubscriptionAdapter;
import net.kyori.event.method.asm.ASMEventExecutorFactory;
@Singleton
public class GDEventManager implements EventManager {
private final EventBus<Event> bus;
private final MethodSubscriptionAdapter<Object> adapter;
public GDEventManager() {
this.bus = new SimpleEventBus<Event>(Event.class);
this.adapter = new SimpleMethodSubscriptionAdapter<>(bus, new ASMEventExecutorFactory<>());
}
@Override
public EventBus<Event> getBus() {
return this.bus;
}
@Override
public void post(Event event) {
this.bus.post(event);
}
@Override
public void register(Object listener) {
this.adapter.register(listener);
}
@Override
public void unregister(Object listener) {
this.adapter.unregister(listener);
}
}

View File

@ -0,0 +1,701 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ShovelType;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.data.PlayerData;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.configuration.PlayerStorageData;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.data.Transaction;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class GDPlayerData implements PlayerData {
public UUID playerID;
public UUID worldUniqueId;
private WeakReference<GDPermissionUser> playerSubject;
private Set<Claim> claimList;
private PlayerStorageData playerStorage;
public Location<World> lastAfkCheckLocation;
public Location<World> lastShovelLocation;
public Location<World> endShovelLocation;
public Location<World> lastValidInspectLocation;
public boolean claimMode = false;
public ShovelType shovelMode = ShovelTypes.BASIC;
public GDClaim claimResizing;
public GDClaim claimSubdividing;
public List<Transaction<BlockSnapshot>> visualBlocks = new ArrayList<>();
public UUID visualClaimId;
public UUID petRecipientUniqueId;
public Task visualRevertTask;
public boolean ignoreClaims = false;
public boolean debugClaimPermissions = false;
public WeakReference<GDClaim> lastClaim = new WeakReference<>(null);
public boolean inTown = false;
public boolean townChat = false;
// Always ignore active contexts by default
// This prevents protection issues when other plugins call getActiveContext
public boolean ignoreActiveContexts = true;
public EventResultCache eventResultCache;
// collide event cache
public int lastCollideEntityId = 0;
public boolean lastCollideEntityResult = false;
private String playerName;
public boolean allowFlight = false;
public boolean ignoreFallDamage = false;
// teleport data
public int teleportDelay = 0;
public Location<World> teleportSourceLocation;
public Location<World> teleportLocation;
public Instant lastPvpTimestamp;
// cached global option values
public int minClaimLevel;
private CreateModeType optionClaimCreateMode;
private Integer optionMaxAccruedBlocks;
// cached permission values
public boolean canManageAdminClaims = false;
public boolean canManageWilderness = false;
public boolean canManageGlobalOptions = false;
public boolean canManageAdminOptions = false;
public boolean canManageOverrideOptions = false;
public boolean canManageFlagDefaults = false;
public boolean canManageFlagOverrides = false;
public boolean bypassBorderCheck = false;
public boolean ignoreAdminClaims = false;
public boolean ignoreBasicClaims = false;
public boolean ignoreTowns = false;
public boolean ignoreWilderness = false;
public boolean dataInitialized = false;
public boolean showVisualFillers = true;
public boolean useRestoreSchematic = false;
private boolean checkedDimensionHeight = false;
public GDPlayerData(UUID worldUniqueId, UUID playerUniqueId, PlayerStorageData playerStorage, GriefDefenderConfig<?> activeConfig, Set<Claim> claims) {
this.worldUniqueId = worldUniqueId;
this.playerID = playerUniqueId;
this.playerStorage = playerStorage;
this.claimList = claims;
this.refreshPlayerOptions();
}
public void refreshPlayerOptions() {
final GriefDefenderConfig<?> activeConfig = GriefDefenderPlugin.getActiveConfig(this.worldUniqueId);
GriefDefenderPlugin.getInstance().executor.execute(() -> {
if (this.playerSubject == null || this.playerSubject.get() == null) {
GDPermissionUser subject = PermissionHolderCache.getInstance().getOrCreateUser(this.playerID);
this.playerSubject = new WeakReference<>(subject);
}
final GDPermissionUser subject = this.playerSubject.get();
final Set<Context> activeContexts = new HashSet<>();
PermissionUtil.getInstance().addActiveContexts(activeContexts, subject);
// permissions
this.bypassBorderCheck = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.BYPASS_BORDER_CHECK, activeContexts).asBoolean();
this.ignoreAdminClaims = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.IGNORE_CLAIMS_ADMIN, activeContexts).asBoolean();
this.ignoreTowns = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.IGNORE_CLAIMS_TOWN, activeContexts).asBoolean();
this.ignoreWilderness = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.IGNORE_CLAIMS_WILDERNESS, activeContexts).asBoolean();
this.ignoreBasicClaims = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.IGNORE_CLAIMS_BASIC, activeContexts).asBoolean();
this.canManageAdminClaims = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.COMMAND_ADMIN_CLAIMS, activeContexts).asBoolean();
this.canManageWilderness = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_WILDERNESS, activeContexts).asBoolean();
this.canManageOverrideOptions = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_OVERRIDE_OPTIONS, activeContexts).asBoolean();
this.canManageGlobalOptions = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_GLOBAL_OPTIONS, activeContexts).asBoolean();
this.canManageAdminOptions = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_ADMIN_OPTIONS, activeContexts).asBoolean();
this.canManageFlagDefaults = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_FLAG_DEFAULTS, activeContexts).asBoolean();
this.canManageFlagOverrides = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.MANAGE_FLAG_OVERRIDES, activeContexts).asBoolean();
this.playerID = subject.getUniqueId();
/*if (this.optionMaxClaimLevel > 255 || this.optionMaxClaimLevel <= 0 || this.optionMaxClaimLevel < this.optionMinClaimLevel) {
this.optionMaxClaimLevel = 255;
}
if (this.optionMinClaimLevel < 0 || this.optionMinClaimLevel >= 255 || this.optionMinClaimLevel > this.optionMaxClaimLevel) {
this.optionMinClaimLevel = 0;
}*/
this.dataInitialized = true;
this.checkedDimensionHeight = false;
});
}
public String getPlayerName() {
if (this.playerName == null) {
GDPermissionUser user = this.playerSubject.get();
if (user == null) {
user = PermissionHolderCache.getInstance().getOrCreateUser(this.playerID);
}
if (user != null) {
this.playerName = user.getFriendlyName();
}
if (this.playerName == null) {
this.playerName = "[unknown]";
}
}
return this.playerName;
}
public void revertActiveVisual(Player player) {
if (this.visualRevertTask != null) {
this.visualRevertTask.cancel();
this.visualRevertTask = null;
}
this.lastShovelLocation = null;
GDClaim claim = null;
if (this.visualClaimId != null) {
claim = (GDClaim) GriefDefenderPlugin.getInstance().dataStore.getClaim(this.worldUniqueId, this.visualClaimId);
if (claim != null) {
claim.playersWatching.remove(this.playerID);
}
}
this.visualClaimId = null;
if (this.visualBlocks.isEmpty()|| !player.getWorld().equals(this.visualBlocks.get(0).getFinal().getLocation().get().getExtent())) {
return;
}
for (int i = 0; i < this.visualBlocks.size(); i++) {
BlockSnapshot snapshot = this.visualBlocks.get(i).getOriginal();
// If original block does not exist, do not send to player
if (snapshot.getState().getType() != snapshot.getLocation().get().getBlockType()) {
if (claim != null) {
claim.markVisualDirty = true;
}
continue;
}
player.sendBlockChange(snapshot.getPosition(), snapshot.getState());
}
this.visualBlocks.clear();
}
@Override
public int getBlocksAccruedPerHour() {
final Integer value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.BLOCKS_ACCRUED_PER_HOUR);
if (value == null) {
return Options.BLOCKS_ACCRUED_PER_HOUR.getDefaultValue();
}
return value;
}
@Override
public int getChestClaimExpiration() {
final Integer value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.CHEST_EXPIRATION);
if (value == null) {
return Options.CHEST_EXPIRATION.getDefaultValue();
}
return value;
}
@Override
public int getCreateClaimLimit(ClaimType type) {
final Integer value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.CREATE_LIMIT, type);
if (value == null) {
return Options.CREATE_LIMIT.getDefaultValue();
}
return value;
}
public CreateModeType getCreateMode() {
final CreateModeType value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(CreateModeType.class), this.getSubject(), Options.CREATE_MODE);
if (value == null || value == CreateModeTypes.UNDEFINED) {
return CreateModeTypes.AREA;
}
return value;
}
@Override
public int getInitialClaimBlocks() {
final Integer value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.INITIAL_BLOCKS);
if (value == null) {
return Options.INITIAL_BLOCKS.getDefaultValue();
}
return value;
}
public double getInternalEconomyBlockCost() {
final Double value = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.ECONOMY_BLOCK_COST);
if (value == null) {
return Options.ECONOMY_BLOCK_COST.getDefaultValue();
}
return value;
}
public int getInternalRemainingClaimBlocks() {
final int initialClaimBlocks = this.getInitialClaimBlocks();
int remainingBlocks = initialClaimBlocks + this.getAccruedClaimBlocks() + this.getBonusClaimBlocks();
for (Claim claim : this.claimList) {
if (claim.isSubdivision()) {
continue;
}
GDClaim gpClaim = (GDClaim) claim;
if ((gpClaim.parent == null || gpClaim.parent.isAdminClaim()) && claim.getData().requiresClaimBlocks()) {
remainingBlocks -= claim.getClaimBlocks();
}
}
return remainingBlocks;
}
@Override
public int getRemainingClaimBlocks() {
final int initialClaimBlocks = this.getInitialClaimBlocks();
int remainingBlocks = initialClaimBlocks + this.getAccruedClaimBlocks() + this.getBonusClaimBlocks();
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
return this.getInternalEconomyAvailablePurchaseCost();
} else {
for (Claim claim : this.claimList) {
if (claim.isSubdivision()) {
continue;
}
GDClaim gpClaim = (GDClaim) claim;
if ((gpClaim.parent == null || gpClaim.parent.isAdminClaim()) && claim.getData().requiresClaimBlocks()) {
remainingBlocks -= claim.getClaimBlocks();
}
}
}
return remainingBlocks;
}
public int getInternalEconomyAvailablePurchaseCost() {
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(this.playerID).orElse(null);
if (playerAccount == null) {
return 0;
}
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final BigDecimal currentFunds = playerAccount.getBalance(defaultCurrency);
final Double economyBlockCost = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.ECONOMY_BLOCK_COST);
return (int) Math.round((currentFunds.doubleValue() / economyBlockCost));
}
return 0;
}
public int getTotalClaimsCost() {
int totalCost = 0;
for (Claim claim : this.claimList) {
if (claim.isSubdivision()) {
continue;
}
final GDClaim gpClaim = (GDClaim) claim;
if ((gpClaim.parent == null || gpClaim.parent.isAdminClaim()) && claim.getData().requiresClaimBlocks()) {
totalCost += claim.getClaimBlocks();
}
}
return totalCost;
}
public double getRemainingChunks() {
final double remainingChunks = this.getRemainingClaimBlocks() / 65536.0;
return Math.round(remainingChunks * 100.0)/100.0;
}
@Override
public int getAccruedClaimBlocks() {
return this.playerStorage.getConfig().getAccruedClaimBlocks();
}
public boolean addAccruedClaimBlocks(int newAccruedClaimBlocks) {
int currentTotal = this.getAccruedClaimBlocks();
if ((currentTotal + newAccruedClaimBlocks) > this.getMaxAccruedClaimBlocks()) {
return false;
}
this.playerStorage.getConfig().setAccruedClaimBlocks(currentTotal + newAccruedClaimBlocks);
return true;
}
public boolean setAccruedClaimBlocks(int newAccruedClaimBlocks) {
if (newAccruedClaimBlocks > this.getMaxAccruedClaimBlocks()) {
return false;
}
this.playerStorage.getConfig().setAccruedClaimBlocks(newAccruedClaimBlocks);
return true;
}
public int getBonusClaimBlocks() {
return this.playerStorage.getConfig().getBonusClaimBlocks();
}
public void setBonusClaimBlocks(int bonusClaimBlocks) {
this.playerStorage.getConfig().setBonusClaimBlocks(bonusClaimBlocks);
}
public CreateModeType getClaimCreateMode() {
if (this.optionClaimCreateMode == null) {
CreateModeType mode = this.getCreateMode();
// default to 0 if invalid
if (mode == null) {
mode = CreateModeTypes.AREA;
}
this.optionClaimCreateMode = mode;
}
return this.optionClaimCreateMode;
}
public void setClaimCreateMode(CreateModeType mode) {
this.optionClaimCreateMode = mode;
}
public boolean canCreateClaim(Player player) {
return canCreateClaim(player, false);
}
public boolean canCreateClaim(Player player, boolean sendMessage) {
final CreateModeType createMode = this.getClaimCreateMode();
if (this.shovelMode == ShovelTypes.BASIC) {
if (createMode == CreateModeTypes.AREA && !player.hasPermission(GDPermissions.CLAIM_CREATE_BASIC)) {
if (sendMessage) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_CREATE);
}
return false;
}
if (createMode == CreateModeTypes.VOLUME && !player.hasPermission(GDPermissions.CLAIM_CUBOID_BASIC)) {
if (sendMessage) {
GriefDefenderPlugin.sendMessage(player,MessageCache.getInstance().PERMISSION_CUBOID);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CUBOID_DISABLED);
}
return false;
}
} else if (this.shovelMode == ShovelTypes.SUBDIVISION) {
if (createMode == CreateModeTypes.AREA && !player.hasPermission(GDPermissions.CLAIM_CREATE_SUBDIVISION)) {
if (sendMessage) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_CREATE);
}
return false;
} else if (!player.hasPermission(GDPermissions.CLAIM_CUBOID_SUBDIVISION)) {
if (sendMessage) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CUBOID);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CUBOID_DISABLED);
}
return false;
}
} else if (this.shovelMode == ShovelTypes.ADMIN) {
if (createMode == CreateModeTypes.AREA && !player.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS)) {
return false;
} else if (!player.hasPermission(GDPermissions.CLAIM_CUBOID_ADMIN)) {
return false;
}
} else if (this.shovelMode == ShovelTypes.TOWN) {
if (createMode == CreateModeTypes.AREA && !player.hasPermission(GDPermissions.CLAIM_CREATE_TOWN)) {
return false;
} else if (!player.hasPermission(GDPermissions.CLAIM_CUBOID_TOWN)) {
return false;
}
}
return true;
}
public void saveAllData() {
this.playerStorage.save();
}
public PlayerStorageData getStorageData() {
return this.playerStorage;
}
public Set<Claim> getClaims() {
return ImmutableSet.copyOf(this.claimList);
}
public Set<Claim> getInternalClaims() {
return this.claimList;
}
public int getClaimTypeCount(ClaimType type) {
int count = 0;
for (Claim claim : this.claimList) {
if (claim.getType() == type) {
count++;
}
}
return count;
}
public void setLastCollideEntityData(int entityId, boolean result) {
this.lastCollideEntityId = entityId;
this.lastCollideEntityResult = result;
}
public void setIgnoreClaims(boolean flag) {
this.ignoreClaims = flag;
}
@Override
public boolean canIgnoreClaim(Claim claim) {
if (claim == null || this.ignoreClaims == false) {
return false;
}
if (claim.isAdminClaim()) {
return this.ignoreAdminClaims;
} else if (claim.isWilderness()) {
return this.ignoreWilderness;
} else if (claim.isTown()) {
return this.ignoreTowns;
}
return this.ignoreBasicClaims;
}
public boolean canManageOption(Player player, GDClaim claim, boolean isGroup) {
if (claim.allowEdit(player) != null) {
return false;
}
if (claim.isWilderness()) {
return player.hasPermission(GDPermissions.MANAGE_WILDERNESS);
}
if (isGroup) {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_SUBDIVISION)) {
return true;
}
} else {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_SUBDIVISION)) {
return true;
}
}
return false;
}
@Override
public int getMaxAccruedClaimBlocks() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS);
}
@Override
public double getAbandonedReturnRatio(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.ABANDON_RETURN_RATIO);
}
@Override
public int getMaxClaimX(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_SIZE_X, type);
}
@Override
public int getMaxClaimY(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_SIZE_Y, type);
}
@Override
public int getMaxClaimZ(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_SIZE_Z, type);
}
@Override
public int getMinClaimX(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MIN_SIZE_X, type);
}
@Override
public int getMinClaimY(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MIN_SIZE_Y, type);
}
@Override
public int getMinClaimZ(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MIN_SIZE_Z, type);
}
@Override
public int getMaxClaimLevel() {
int maxClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_LEVEL);
if (!this.checkedDimensionHeight) {
final World world = Sponge.getServer().getWorld(this.worldUniqueId).orElse(null);
if (world != null) {
final int buildHeight = world.getDimension().getBuildHeight() - 1;
if (buildHeight < maxClaimLevel) {
maxClaimLevel = buildHeight;
}
}
this.checkedDimensionHeight = true;
}
return maxClaimLevel;
}
@Override
public int getMinClaimLevel() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MIN_LEVEL);
}
@Override
public double getEconomyClaimBlockCost() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.ECONOMY_BLOCK_COST);
}
@Override
public double getEconomyClaimBlockReturn() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.ECONOMY_BLOCK_SELL_RETURN);
}
@Override
public double getTaxRate(ClaimType type) {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), this.getSubject(), Options.TAX_RATE, type);
}
@Override
public String getSubjectId() {
return this.getSubject().getIdentifier();
}
public GDPermissionUser getSubject() {
this.playerSubject = null;
if (this.playerSubject == null || this.playerSubject.get() == null) {
GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(this.playerID);
this.playerSubject = new WeakReference<>(user);
}
return this.playerSubject.get();
}
public void sendTaxExpireMessage(Player player, GDClaim claim) {
final double taxRate = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), player, Options.TAX_RATE, claim);
final double taxOwed = claim.getClaimBlocks() * taxRate;
final double remainingDays = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.TAX_EXPIRATION_DAYS_KEEP, claim);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.TAX_CLAIM_EXPIRED, ImmutableMap.of(
"days", remainingDays,
"amount", taxOwed));
GriefDefenderPlugin.sendClaimDenyMessage(claim, player, message);
}
public double getTotalTax() {
double totalTax = 0;
final GDPermissionUser subject = this.getSubject();
for (Claim claim : this.getInternalClaims()) {
double playerTaxRate = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), subject, Options.TAX_RATE, claim);
totalTax += (claim.getClaimBlocks() / 256) * playerTaxRate;
}
return totalTax;
}
public boolean inPvpCombat(World world) {
if (this.lastPvpTimestamp == null) {
return false;
}
final Instant now = Instant.now();
final int combatTimeout = GriefDefenderPlugin.getActiveConfig(world.getProperties()).getConfig().pvp.combatTimeout;
if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null;
return false;
}
return true;
}
public void onDisconnect() {
this.visualBlocks.clear();
this.claimMode = false;
this.lastShovelLocation = null;
this.eventResultCache = null;
this.claimResizing = null;
this.claimSubdividing = null;
this.visualClaimId = null;
if (this.visualRevertTask != null) {
this.visualRevertTask.cancel();
this.visualRevertTask = null;
}
}
}

View File

@ -0,0 +1,78 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.griefdefender.util.BootstrapUtil;
import me.lucko.jarrelocator.JarRelocator;
import me.lucko.jarrelocator.Relocation;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GDRelocator {
private static GDRelocator instance;
private List<Relocation> rules;
public static GDRelocator getInstance() {
if (instance == null) {
instance = new GDRelocator();
}
return instance;
}
public GDRelocator() {
this.rules = new ArrayList<>();
for (String name : GDBootstrap.getInstance().getRelocateList()) {
final String[] parts = name.split(":");
final String key = parts[0];
final String relocated = parts[1];
this.rules.add(new Relocation(key, "com.griefdefender.lib." + relocated));
}
}
public void relocateJars(Map<String, File> jarMap) {
for (Map.Entry<String, File> mapEntry : jarMap.entrySet()) {
final String name = mapEntry.getKey();
final File input = mapEntry.getValue();
final File output = Paths.get(input.getParentFile().getPath()).resolve(input.getName().replace(".jar", "") + "-shaded.jar").toFile();
if (!output.exists()) {
// Relocate
JarRelocator relocator = new JarRelocator(input, output, this.rules);
try {
relocator.run();
} catch (IOException e) {
throw new RuntimeException("Unable to relocate", e);
}
}
BootstrapUtil.addUrlToClassLoader(name, output);
}
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
public class GDTimings {
public static final Timing BLOCK_BREAK_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockBreak");
public static final Timing BLOCK_COLLIDE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockCollide");
public static final Timing BLOCK_NOTIFY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockNotify");
public static final Timing BLOCK_PLACE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockPlace");
public static final Timing BLOCK_POST_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockPost");
public static final Timing BLOCK_PRE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onBlockPre");
public static final Timing ENTITY_EXPLOSION_PRE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityExplosionPre");
public static final Timing ENTITY_EXPLOSION_DETONATE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityExplosionDetonate");
public static final Timing ENTITY_ATTACK_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityAttack");
public static final Timing ENTITY_COLLIDE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityCollide");
public static final Timing ENTITY_DAMAGE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityDamage");
public static final Timing ENTITY_DAMAGE_MONITOR_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityDamageMonitor");
public static final Timing ENTITY_DEATH_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityDeath");
public static final Timing ENTITY_DROP_ITEM_DEATH_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityDropDeathItem");
public static final Timing ENTITY_MOUNT_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityMount");
public static final Timing ENTITY_MOVE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityMove");
public static final Timing ENTITY_SPAWN_PRE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntitySpawnPre");
public static final Timing ENTITY_SPAWN_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntitySpawn");
public static final Timing ENTITY_TELEPORT_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onEntityTeleport");
public static final Timing PLAYER_CHANGE_HELD_ITEM_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerChangeHeldItem");
public static final Timing PLAYER_CHAT_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerChat");
public static final Timing PLAYER_COMMAND_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerCommand");
public static final Timing PLAYER_DEATH_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerDeath");
public static final Timing PLAYER_DISPENSE_ITEM_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerDispenseItem");
public static final Timing PLAYER_LOGIN_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerLogin");
public static final Timing PLAYER_HANDLE_SHOVEL_ACTION = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerHandleShovelAction");
public static final Timing PLAYER_INTERACT_BLOCK_PRIMARY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractBlockPrimary");
public static final Timing PLAYER_INTERACT_BLOCK_SECONDARY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractBlockSecondary");
public static final Timing PLAYER_INTERACT_ENTITY_PRIMARY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractEntityPrimary");
public static final Timing PLAYER_INTERACT_ENTITY_SECONDARY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractEntitySecondary");
public static final Timing PLAYER_INTERACT_INVENTORY_CLICK_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractInventoryClick");
public static final Timing PLAYER_INTERACT_INVENTORY_CLOSE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractInventoryClose");
public static final Timing PLAYER_INTERACT_INVENTORY_OPEN_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInteractInventoryOpen");
public static final Timing PLAYER_INVESTIGATE_CLAIM = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerInvestigateClaim");
public static final Timing PLAYER_JOIN_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerJoin");
public static final Timing PLAYER_KICK_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerKick");
public static final Timing PLAYER_PICKUP_ITEM_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerPickupItem");
public static final Timing PLAYER_QUIT_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerQuit");
public static final Timing PLAYER_RESPAWN_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerRespawn");
public static final Timing PLAYER_USE_ITEM_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onPlayerUseItem");
public static final Timing SIGN_CHANGE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onSignChange");
public static final Timing PROJECTILE_IMPACT_BLOCK_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onProjectileImpactBlock");
public static final Timing PROJECTILE_IMPACT_ENTITY_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onProjectileImpactEntity");
public static final Timing EXPLOSION_PRE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onExplosionPre");
public static final Timing EXPLOSION_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onExplosionDetonate");
public static final Timing CLAIM_GETCLAIM = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "getClaimAt");
public static final Timing WORLD_LOAD_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onWorldSave");
public static final Timing WORLD_SAVE_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onWorldSave");
public static final Timing WORLD_UNLOAD_EVENT = Timings.of(GriefDefenderPlugin.getInstance().pluginContainer, "onWorldSave");
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender;
import com.google.inject.Singleton;
import com.griefdefender.api.Version;
@Singleton
public class GDVersion implements Version {
public static final double API_VERSION = 0.91;
@Override
public double getApiVersion() {
return API_VERSION;
}
@Override
public String getImplementationVersion() {
return GriefDefenderPlugin.IMPLEMENTATION_VERSION;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.cache;
import java.util.UUID;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.claim.GDClaim;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.Sponge;
public class EventResultCache {
public final String eventFlag;
public final Tristate lastResult;
public final int lastTickCounter;
public final UUID lastClaim;
public final String lastTrust;
public EventResultCache(Claim claim, String flag, Tristate result) {
this(claim, flag, result, null);
}
public EventResultCache(Claim claim, String flag, Tristate result, String trust) {
this.eventFlag = flag;
this.lastClaim = claim.getUniqueId();
this.lastResult = result;
this.lastTickCounter = Sponge.getServer().getRunningTimeTicks();
this.lastTrust = trust == null ? "cache" : trust;
}
public Tristate checkEventResultCache(GDClaim claim) {
return this.checkEventResultCache(claim, null);
}
public Tristate checkEventResultCache(GDClaim claim, String flag) {
if (Sponge.getServer().getRunningTimeTicks() > this.lastTickCounter) {
return Tristate.UNDEFINED;
}
if (claim.getUniqueId().equals(this.lastClaim)) {
if (flag != null && this.eventFlag != null && !this.eventFlag.equalsIgnoreCase(flag)) {
return Tristate.UNDEFINED;
}
return this.lastResult;
}
return Tristate.UNDEFINED;
}
}

View File

@ -0,0 +1,772 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.cache;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.flag.GDFlag;
import com.griefdefender.permission.option.GDOption;
import com.griefdefender.registry.FlagRegistryModule;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.Component;
public class MessageCache {
private static MessageCache instance;
static {
instance = new MessageCache();
}
public static MessageCache getInstance() {
return instance;
}
public Component ABANDON_ALL_DELAY_WARNING;
public Component ABANDON_ALL_WARNING;
public Component ABANDON_CLAIM_MISSING;
public Component ABANDON_TOP_LEVEL;
public Component ABANDON_TOWN_CHILDREN;
public Component ABANDON_WARNING;
public Component BANK_CLICK_VIEW_TRANSACTIONS;
public Component BANK_DEPOSIT_NO_FUNDS;
public Component BANK_TITLE_TRANSACTIONS;
public Component BANK_TAX_SYSTEM_DISABLED;
public Component CLAIM_AUTOMATIC_NOTIFICATION;
public Component CLAIM_CHEST_CONFIRMATION;
public Component CLAIM_CHILDREN_WARNING;
public Component CLAIM_DISABLED_WORLD;
public Component CLAIM_FAREWELL_CLEAR;
public Component CLAIM_GREETING_CLEAR;
public Component CLAIM_IGNORE;
public Component CLAIM_NO_CLAIMS;
public Component CLAIM_NOT_FOUND;
public Component CLAIM_NOT_YOURS;
public Component CLAIM_OWNER_ALREADY;
public Component CLAIM_OWNER_ONLY;
public Component CLAIM_RESPECTING;
public Component CLAIM_RESTORE_SUCCESS;
public Component CLAIM_TOO_FAR;
public Component CLAIMINFO_UI_ADMIN_SETTINGS;
public Component CLAIMINFO_UI_BANK_INFO;
public Component CLAIMINFO_UI_CLAIM_EXPIRATION;
public Component CLAIMINFO_UI_CLICK_ADMIN;
public Component CLAIMINFO_UI_CLICK_BANK;
public Component CLAIMINFO_UI_CLICK_TOGGLE;
public Component CLAIMINFO_UI_DENY_MESSAGES;
public Component CLAIMINFO_UI_FLAG_OVERRIDES;
public Component CLAIMINFO_UI_FOR_SALE;
public Component CLAIMINFO_UI_INHERIT_PARENT;
public Component CLAIMINFO_UI_LAST_ACTIVE;
public Component CLAIMINFO_UI_NORTH_CORNERS;
public Component CLAIMINFO_UI_PVP_OVERRIDES;
public Component CLAIMINFO_UI_REQUIRES_CLAIM_BLOCKS;
public Component CLAIMINFO_UI_RETURN_BANKINFO;
public Component CLAIMINFO_UI_RETURN_CLAIMINFO;
public Component CLAIMINFO_UI_RETURN_SETTINGS;
public Component CLAIMINFO_UI_SIZE_RESTRICTIONS;
public Component CLAIMINFO_UI_SOUTH_CORNERS;
public Component CLAIMINFO_UI_TELEPORT_FEATURE;
public Component CLAIMINFO_UI_TELEPORT_SPAWN;
public Component CLAIMINFO_UI_TITLE_CLAIMINFO;
public Component CLAIMINFO_UI_TOWN_SETTINGS;
public Component CLAIMLIST_UI_CLICK_INFO;
public Component CLAIMLIST_UI_CLICK_PURCHASE;
public Component CLAIMLIST_UI_CLICK_VIEW_CHILDREN;
public Component CLAIMLIST_UI_CLICK_VIEW_CLAIMS;
public Component CLAIMLIST_UI_NO_CLAIMS_FOUND;
public Component CLAIMLIST_UI_RETURN_CLAIMSLIST;
public Component CLAIMLIST_UI_TITLE;
public Component CLAIMLIST_UI_TITLE_CHILD_CLAIMS;
public Component COMMAND_CLAIMBUY_TITLE;
public Component COMMAND_CLAIMCLEAR_UUID_DENY;
public Component COMMAND_CLAIMFLAGDEBUG_DISABLED;
public Component COMMAND_CLAIMFLAGDEBUG_ENABLED;
public Component COMMAND_CLAIMINFO_NOT_FOUND;
public Component COMMAND_CLAIMINFO_UUID_REQUIRED;
public Component COMMAND_CLAIMINHERIT_DISABLED;
public Component COMMAND_CLAIMINHERIT_ENABLED;
public Component COMMAND_CLAIMMODE_DISABLED;
public Component COMMAND_CLAIMMODE_ENABLED;
public Component COMMAND_CUBOID_DISABLED;
public Component COMMAND_CUBOID_ENABLED;
public Component COMMAND_INHERIT_ONLY_CHILD;
public Component COMMAND_INVALID;
public Component COMMAND_INVALID_PLAYER_GROUP;
public Component COMMAND_NOT_AVAILABLE_ECONOMY;
public Component COMMAND_PET_CONFIRMATION;
public Component COMMAND_PET_TRANSFER_READY;
public Component COMMAND_PET_TRANSFER_CANCEL;
public Component COMMAND_WORLDEDIT_MISSING;
public Component CREATE_CANCEL;
public Component CREATE_CUBOID_DISABLED;
public Component CREATE_OVERLAP;
public Component CREATE_OVERLAP_SHORT;
public Component CREATE_SUBDIVISION_FAIL;
public Component CREATE_SUBDIVISION_ONLY;
public Component DEBUG_NO_RECORDS;
public Component DEBUG_PASTE_SUCCESS;
public Component DEBUG_RECORD_END;
public Component DEBUG_RECORD_START;
public Component DEBUG_TIME_ELAPSED;
public Component ECONOMY_BLOCK_BUY_INVALID;
public Component ECONOMY_BLOCK_BUY_SELL_DISABLED;
public Component ECONOMY_BLOCK_NOT_AVAILABLE;
public Component ECONOMY_BLOCK_ONLY_BUY;
public Component ECONOMY_BLOCK_ONLY_SELL;
public Component ECONOMY_CLAIM_NOT_FOR_SALE;
public Component ECONOMY_CLAIM_SALE_CANCELLED;
public Component ECONOMY_NOT_INSTALLED;
public Component ECONOMY_VIRTUAL_NOT_SUPPORTED;
public Component FEATURE_NOT_AVAILABLE;
public Component FLAG_DESCRIPTION_CUSTOM_BLOCK_BREAK;
public Component FLAG_DESCRIPTION_CUSTOM_BLOCK_GROW;
public Component FLAG_DESCRIPTION_CUSTOM_BLOCK_PLACE;
public Component FLAG_DESCRIPTION_CUSTOM_BLOCK_SPREAD;
public Component FLAG_DESCRIPTION_CUSTOM_ENDERPEARL;
public Component FLAG_DESCRIPTION_CUSTOM_EXIT_PLAYER;
public Component FLAG_DESCRIPTION_CUSTOM_EXPLOSION_BLOCK;
public Component FLAG_DESCRIPTION_CUSTOM_EXPLOSION_ENTITY;
public Component FLAG_DESCRIPTION_CUSTOM_EXP_DROP;
public Component FLAG_DESCRIPTION_CUSTOM_FALL_DAMAGE;
public Component FLAG_DESCRIPTION_CUSTOM_INTERACT_BLOCK;
public Component FLAG_DESCRIPTION_CUSTOM_INTERACT_ENTITY;
public Component FLAG_DESCRIPTION_CUSTOM_INTERACT_INVENTORY;
public Component FLAG_DESCRIPTION_CUSTOM_INVINCIBLE;
public Component FLAG_DESCRIPTION_CUSTOM_ITEM_DROP;
public Component FLAG_DESCRIPTION_CUSTOM_ITEM_PICKUP;
public Component FLAG_DESCRIPTION_CUSTOM_MONSTER_DAMAGE;
public Component FLAG_DESCRIPTION_CUSTOM_PISTONS;
public Component FLAG_DESCRIPTION_CUSTOM_PORTAL_USE;
public Component FLAG_DESCRIPTION_CUSTOM_SPAWN_AQUATIC;
public Component FLAG_DESCRIPTION_CUSTOM_SPAWN_AMBIENT;
public Component FLAG_DESCRIPTION_CUSTOM_SPAWN_ANIMAL;
public Component FLAG_DESCRIPTION_CUSTOM_SPAWN_MONSTER;
public Component FLAG_DESCRIPTION_CUSTOM_TELEPORT_FROM;
public Component FLAG_DESCRIPTION_CUSTOM_TELEPORT_TO;
public Component FLAG_DESCRIPTION_CUSTOM_USE;
public Component FLAG_DESCRIPTION_CUSTOM_VEHICLE_DESTROY;
public Component FLAG_DESCRIPTION_CUSTOM_WITHER_DAMAGE;
public Component FLAG_DESCRIPTION_CUSTOM_BLOCK_TRAMPLING;
public Component FLAG_DESCRIPTION_CUSTOM_CHEST_ACCESS;
public Component FLAG_DESCRIPTION_CUSTOM_CHORUS_FRUIT_TELEPORT;
public Component FLAG_DESCRIPTION_CUSTOM_CROP_GROWTH;
public Component FLAG_DESCRIPTION_CUSTOM_DAMAGE_ANIMALS;
public Component FLAG_DESCRIPTION_CUSTOM_ENDERMAN_GRIEF;
public Component FLAG_DESCRIPTION_CUSTOM_ENTER_PLAYER;
public Component FLAG_DESCRIPTION_CUSTOM_EXPLOSION_CREEPER;
public Component FLAG_DESCRIPTION_CUSTOM_EXPLOSION_TNT;
public Component FLAG_DESCRIPTION_CUSTOM_FIRE_DAMAGE;
public Component FLAG_DESCRIPTION_CUSTOM_FIRE_SPREAD;
public Component FLAG_DESCRIPTION_CUSTOM_GRASS_GROWTH;
public Component FLAG_DESCRIPTION_CUSTOM_ICE_FORM;
public Component FLAG_DESCRIPTION_CUSTOM_ICE_MELT;
public Component FLAG_DESCRIPTION_CUSTOM_LAVA_FLOW;
public Component FLAG_DESCRIPTION_CUSTOM_LEAF_DECAY;
public Component FLAG_DESCRIPTION_CUSTOM_LIGHTNING;
public Component FLAG_DESCRIPTION_CUSTOM_LIGHTER;
public Component FLAG_DESCRIPTION_CUSTOM_MUSHROOM_GROWTH;
public Component FLAG_DESCRIPTION_CUSTOM_MYCELIUM_SPREAD;
public Component FLAG_DESCRIPTION_CUSTOM_PVP;
public Component FLAG_DESCRIPTION_CUSTOM_RIDE;
public Component FLAG_DESCRIPTION_CUSTOM_SLEEP;
public Component FLAG_DESCRIPTION_CUSTOM_SNOW_FALL;
public Component FLAG_DESCRIPTION_CUSTOM_SNOW_MELT;
public Component FLAG_DESCRIPTION_CUSTOM_SNOWMAN_TRAIL;
public Component FLAG_DESCRIPTION_CUSTOM_SOIL_DRY;
public Component FLAG_DESCRIPTION_CUSTOM_VEHICLE_PLACE;
public Component FLAG_DESCRIPTION_CUSTOM_VINE_GROWTH;
public Component FLAG_DESCRIPTION_CUSTOM_WATER_FLOW;
public Component FLAG_DESCRIPTION_BLOCK_BREAK;
public Component FLAG_DESCRIPTION_BLOCK_GROW;
public Component FLAG_DESCRIPTION_BLOCK_MODIFY;
public Component FLAG_DESCRIPTION_BLOCK_PLACE;
public Component FLAG_DESCRIPTION_BLOCK_SPREAD;
public Component FLAG_DESCRIPTION_COLLIDE_BLOCK;
public Component FLAG_DESCRIPTION_COLLIDE_ENTITY;
public Component FLAG_DESCRIPTION_COMMAND_EXECUTE;
public Component FLAG_DESCRIPTION_COMMAND_EXECUTE_PVP;
public Component FLAG_DESCRIPTION_ENTER_CLAIM;
public Component FLAG_DESCRIPTION_ENTITY_CHUNK_SPAWN;
public Component FLAG_DESCRIPTION_ENTITY_DAMAGE;
public Component FLAG_DESCRIPTION_ENTITY_RIDING;
public Component FLAG_DESCRIPTION_ENTITY_SPAWN;
public Component FLAG_DESCRIPTION_ENTITY_TELEPORT_FROM;
public Component FLAG_DESCRIPTION_ENTITY_TELEPORT_TO;
public Component FLAG_DESCRIPTION_EXIT_CLAIM;
public Component FLAG_DESCRIPTION_EXPLOSION_BLOCK;
public Component FLAG_DESCRIPTION_EXPLOSION_ENTITY;
public Component FLAG_DESCRIPTION_INTERACT_BLOCK_PRIMARY;
public Component FLAG_DESCRIPTION_INTERACT_BLOCK_SECONDARY;
public Component FLAG_DESCRIPTION_INTERACT_ENTITY_PRIMARY;
public Component FLAG_DESCRIPTION_INTERACT_ENTITY_SECONDARY;
public Component FLAG_DESCRIPTION_INTERACT_INVENTORY;
public Component FLAG_DESCRIPTION_INTERACT_ITEM_PRIMARY;
public Component FLAG_DESCRIPTION_INTERACT_ITEM_SECONDARY;
public Component FLAG_DESCRIPTION_INTERACT_INVENTORY_CLICK;
public Component FLAG_DESCRIPTION_ITEM_DROP;
public Component FLAG_DESCRIPTION_ITEM_PICKUP;
public Component FLAG_DESCRIPTION_ITEM_SPAWN;
public Component FLAG_DESCRIPTION_ITEM_USE;
public Component FLAG_DESCRIPTION_LEAF_DECAY;
public Component FLAG_DESCRIPTION_LIQUID_FLOW;
public Component FLAG_DESCRIPTION_PORTAL_USE;
public Component FLAG_DESCRIPTION_PROJECTILE_IMPACT_BLOCK;
public Component FLAG_DESCRIPTION_PROJECTILE_IMPACT_ENTITY;
public Component FLAG_RESET_SUCCESS;
public Component FLAG_RESET_WARNING;
public Component FLAG_UI_CLICK_ALLOW;
public Component FLAG_UI_CLICK_DENY;
public Component FLAG_UI_CLICK_REMOVE;
public Component FLAG_UI_INFO_CLAIM;
public Component FLAG_UI_INFO_DEFAULT;
public Component FLAG_UI_INFO_INHERIT;
public Component FLAG_UI_INFO_OVERRIDE;
public Component FLAG_UI_OVERRIDE_NO_PERMISSION;
public Component FLAG_UI_RETURN_FLAGS;
public Component LABEL_ACCESSORS;
public Component LABEL_AREA;
public Component LABEL_BLOCKS;
public Component LABEL_BUILDERS;
public Component LABEL_BUY;
public Component LABEL_CHILDREN;
public Component LABEL_CONFIRM;
public Component LABEL_CONTAINERS;
public Component LABEL_CONTEXT;
public Component LABEL_CREATED;
public Component LABEL_DISPLAYING;
public Component LABEL_EXPIRED;
public Component LABEL_FAREWELL;
public Component LABEL_FLAG;
public Component LABEL_GREETING;
public Component LABEL_GROUP;
public Component LABEL_INHERIT;
public Component LABEL_LOCATION;
public Component LABEL_MANAGERS;
public Component LABEL_NAME;
public Component LABEL_NO;
public Component LABEL_OUTPUT;
public Component LABEL_OWNER;
public Component LABEL_PERMISSION;
public Component LABEL_PLAYER;
public Component LABEL_PRICE;
public Component LABEL_RAID;
public Component LABEL_RESIZABLE;
public Component LABEL_RESULT;
public Component LABEL_SCHEMATIC;
public Component LABEL_SOURCE;
public Component LABEL_SPAWN;
public Component LABEL_TARGET;
public Component LABEL_TRUST;
public Component LABEL_TYPE;
public Component LABEL_WORLD;
public Component LABEL_UNKNOWN;
public Component LABEL_USER;
public Component LABEL_YES;
public Component MODE_ADMIN;
public Component MODE_BASIC;
public Component MODE_NATURE;
public Component MODE_SUBDIVISION;
public Component MODE_TOWN;
public Component OPTION_DESCRIPTION_ABANDON_DELAY;
public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO;
public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR;
public Component OPTION_DESCRIPTION_CHEST_EXPIRATION;
public Component OPTION_DESCRIPTION_CREATE_LIMIT;
public Component OPTION_DESCRIPTION_CREATE_MODE;
public Component OPTION_DESCRIPTION_ECONOMY_BLOCK_COST;
public Component OPTION_DESCRIPTION_ECONOMY_BLOCK_SELL_RETURN;
public Component OPTION_DESCRIPTION_EXPIRATION;
public Component OPTION_DESCRIPTION_INITIAL_BLOCKS;
public Component OPTION_DESCRIPTION_MAX_ACCRUED_BLOCKS;
public Component OPTION_DESCRIPTION_MAX_LEVEL;
public Component OPTION_DESCRIPTION_MAX_SIZE_X;
public Component OPTION_DESCRIPTION_MAX_SIZE_Y;
public Component OPTION_DESCRIPTION_MAX_SIZE_Z;
public Component OPTION_DESCRIPTION_MIN_LEVEL;
public Component OPTION_DESCRIPTION_MIN_SIZE_X;
public Component OPTION_DESCRIPTION_MIN_SIZE_Y;
public Component OPTION_DESCRIPTION_MIN_SIZE_Z;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND;
public Component OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER;
public Component OPTION_DESCRIPTION_PLAYER_GAMEMODE;
public Component OPTION_DESCRIPTION_PLAYER_HEALTH_REGEN;
public Component OPTION_DESCRIPTION_PLAYER_KEEP_INVENTORY;
public Component OPTION_DESCRIPTION_PLAYER_KEEP_LEVEL;
public Component OPTION_DESCRIPTION_PLAYER_WALK_SPEED;
public Component OPTION_DESCRIPTION_PLAYER_WEATHER;
public Component OPTION_DESCRIPTION_RADIUS_LIST;
public Component OPTION_DESCRIPTION_RADIUS_INSPECT;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP;
public Component OPTION_DESCRIPTION_TAX_RATE;
public Component OPTION_PLAYER_DENY_FLIGHT;
public Component OWNER_ADMIN;
public Component PERMISSION_ASSIGN_WITHOUT_HAVING;
public Component PERMISSION_CLAIM_CREATE;
public Component PERMISSION_CLAIM_ENTER;
public Component PERMISSION_CLAIM_EXIT;
public Component PERMISSION_CLAIM_LIST;
public Component PERMISSION_CLAIM_RESET_FLAGS_SELF;
public Component PERMISSION_CLAIM_RESIZE;
public Component PERMISSION_CLAIM_SALE;
public Component PERMISSION_CLAIM_TRANSFER_ADMIN;
public Component PERMISSION_CLEAR;
public Component PERMISSION_CLEAR_ALL;
public Component PERMISSION_COMMAND_TRUST;
public Component PERMISSION_CUBOID;
public Component PERMISSION_EDIT_CLAIM;
public Component PERMISSION_FIRE_SPREAD;
public Component PERMISSION_FLAG_DEFAULTS;
public Component PERMISSION_FLAG_OVERRIDES;
public Component PERMISSION_FLAG_USE;
public Component PERMISSION_FLOW_LIQUID;
public Component PERMISSION_GLOBAL_OPTION;
public Component PERMISSION_GRANT;
public Component PERMISSION_GROUP_OPTION;
public Component PERMISSION_OPTION_DEFAULTS;
public Component PERMISSION_OPTION_OVERRIDES;
public Component PERMISSION_OPTION_USE;
public Component PERMISSION_OVERRIDE_DENY;
public Component PERMISSION_PLAYER_ADMIN_FLAGS;
public Component PERMISSION_PLAYER_OPTION;
public Component PERMISSION_PLAYER_VIEW_OTHERS;
public Component PERMISSION_VISUAL_CLAIMS_NEARBY;
public Component PLAYERINFO_UI_TITLE;
public Component PLUGIN_EVENT_CANCEL;
public Component PLUGIN_RELOAD;
public Component PVP_CLAIM_NOT_ALLOWED;
public Component PVP_SOURCE_NOT_ALLOWED;
public Component PVP_TARGET_NOT_ALLOWED;
public Component RESIZE_OVERLAP;
public Component RESIZE_OVERLAP_SUBDIVISION;
public Component RESIZE_SAME_LOCATION;
public Component RESIZE_START;
public Component SCHEMATIC_ABANDON_ALL_RESTORE_WARNING;
public Component SCHEMATIC_ABANDON_RESTORE_WARNING;
public Component SCHEMATIC_CREATE;
public Component SCHEMATIC_CREATE_COMPLETE;
public Component SCHEMATIC_CREATE_FAIL;
public Component SCHEMATIC_NONE;
public Component SPAWN_NOT_SET;
public Component TELEPORT_MOVE_CANCEL;
public Component TELEPORT_NO_SAFE_LOCATION;
public Component TITLE_ACCESSOR;
public Component TITLE_ALL;
public Component TITLE_BUILDER;
public Component TITLE_CLAIM;
public Component TITLE_CONTAINER;
public Component TITLE_DEFAULT;
public Component TITLE_INHERIT;
public Component TITLE_MANAGER;
public Component TITLE_OWN;
public Component TITLE_OVERRIDE;
public Component TOWN_CHAT_DISABLED;
public Component TOWN_CHAT_ENABLED;
public Component TOWN_NOT_FOUND;
public Component TOWN_NOT_IN;
public Component TOWN_OWNER;
public Component TOWN_TAG_CLEAR;
public Component TOWN_TAX_NO_CLAIMS;
public Component TRUST_CLICK_SHOW_LIST;
public Component TRUST_INVALID;
public Component TRUST_LIST_HEADER;
public Component TRUST_NO_CLAIMS;
public Component TRUST_SELF;
public Component UI_CLICK_CONFIRM;
public Component UNTRUST_NO_CLAIMS;
public Component UNTRUST_SELF;
public void loadCache() {
ABANDON_ALL_DELAY_WARNING = MessageStorage.MESSAGE_DATA.getMessage("abandon-all-delay-warning");
ABANDON_ALL_WARNING = MessageStorage.MESSAGE_DATA.getMessage("abandon-all-warning");
ABANDON_CLAIM_MISSING = MessageStorage.MESSAGE_DATA.getMessage("abandon-claim-missing");
ABANDON_TOP_LEVEL = MessageStorage.MESSAGE_DATA.getMessage("abandon-top-level");
ABANDON_TOWN_CHILDREN = MessageStorage.MESSAGE_DATA.getMessage("abandon-town-children");
ABANDON_WARNING = MessageStorage.MESSAGE_DATA.getMessage("abandon-warning");
BANK_CLICK_VIEW_TRANSACTIONS = MessageStorage.MESSAGE_DATA.getMessage("bank-click-view-transactions");
BANK_DEPOSIT_NO_FUNDS = MessageStorage.MESSAGE_DATA.getMessage("bank-deposit-no-funds");
BANK_TAX_SYSTEM_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("bank-tax-system-disabled");
BANK_TITLE_TRANSACTIONS = MessageStorage.MESSAGE_DATA.getMessage("bank-title-transactions");
CLAIM_AUTOMATIC_NOTIFICATION = MessageStorage.MESSAGE_DATA.getMessage("claim-automatic-notification");
CLAIM_CHEST_CONFIRMATION = MessageStorage.MESSAGE_DATA.getMessage("claim-chest-confirmation");
CLAIM_CHILDREN_WARNING = MessageStorage.MESSAGE_DATA.getMessage("claim-children-warning");
CLAIM_DISABLED_WORLD = MessageStorage.MESSAGE_DATA.getMessage("claim-disabled-world");
CLAIM_FAREWELL_CLEAR = MessageStorage.MESSAGE_DATA.getMessage("claim-farewell-clear");
CLAIM_GREETING_CLEAR = MessageStorage.MESSAGE_DATA.getMessage("claim-greeting-clear");
CLAIM_IGNORE = MessageStorage.MESSAGE_DATA.getMessage("claim-ignore");
CLAIM_NO_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claim-no-claims");
CLAIM_NOT_FOUND = MessageStorage.MESSAGE_DATA.getMessage("claim-not-found");
CLAIM_NOT_YOURS = MessageStorage.MESSAGE_DATA.getMessage("claim-not-yours");
CLAIM_OWNER_ALREADY = MessageStorage.MESSAGE_DATA.getMessage("claim-owner-already");
CLAIM_OWNER_ONLY = MessageStorage.MESSAGE_DATA.getMessage("claim-owner-only");
CLAIM_RESPECTING = MessageStorage.MESSAGE_DATA.getMessage("claim-respecting");
CLAIM_RESTORE_SUCCESS = MessageStorage.MESSAGE_DATA.getMessage("claim-restore-success");
CLAIM_TOO_FAR = MessageStorage.MESSAGE_DATA.getMessage("claim-too-far");
CLAIMINFO_UI_ADMIN_SETTINGS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-admin-settings");
CLAIMINFO_UI_BANK_INFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-bank-info");
CLAIMINFO_UI_CLAIM_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-claim-expiration");
CLAIMINFO_UI_CLICK_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-admin");
CLAIMINFO_UI_CLICK_BANK = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-bank");
CLAIMINFO_UI_CLICK_TOGGLE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-toggle");
CLAIMINFO_UI_DENY_MESSAGES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-deny-messages");
CLAIMINFO_UI_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-flag-overrides");
CLAIMINFO_UI_FOR_SALE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-for-sale");
CLAIMINFO_UI_INHERIT_PARENT = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-inherit-parent");
CLAIMINFO_UI_LAST_ACTIVE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-last-active");
CLAIMINFO_UI_NORTH_CORNERS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-north-corners");
CLAIMINFO_UI_PVP_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-pvp-overrides");
CLAIMINFO_UI_REQUIRES_CLAIM_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-requires-claim-blocks");
CLAIMINFO_UI_RETURN_BANKINFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-return-bankinfo");
CLAIMINFO_UI_RETURN_CLAIMINFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-return-claiminfo");
CLAIMINFO_UI_RETURN_SETTINGS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-return-settings");
CLAIMINFO_UI_SIZE_RESTRICTIONS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-size-restrictions");
CLAIMINFO_UI_SOUTH_CORNERS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-south-corners");
CLAIMINFO_UI_TELEPORT_FEATURE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-teleport-feature");
CLAIMINFO_UI_TELEPORT_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-teleport-spawn");
CLAIMINFO_UI_TITLE_CLAIMINFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-title-claiminfo");
CLAIMINFO_UI_TOWN_SETTINGS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-town-settings");
CLAIMLIST_UI_CLICK_INFO = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-info");
CLAIMLIST_UI_CLICK_PURCHASE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-purchase");
CLAIMLIST_UI_CLICK_VIEW_CHILDREN = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-view-children");
CLAIMLIST_UI_CLICK_VIEW_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-view-claims");
CLAIMLIST_UI_NO_CLAIMS_FOUND = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-no-claims-found");
CLAIMLIST_UI_RETURN_CLAIMSLIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-return-claimlist");
CLAIMLIST_UI_TITLE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title");
CLAIMLIST_UI_TITLE_CHILD_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title-child-claims");
COMMAND_CLAIMBUY_TITLE = MessageStorage.MESSAGE_DATA.getMessage("command-claimbuy-title");
COMMAND_CLAIMCLEAR_UUID_DENY = MessageStorage.MESSAGE_DATA.getMessage("command-claimclear-uuid-deny");
COMMAND_CLAIMFLAGDEBUG_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimflagdebug-disabled");
COMMAND_CLAIMFLAGDEBUG_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimflagdebug-enabled");
COMMAND_CLAIMINFO_NOT_FOUND = MessageStorage.MESSAGE_DATA.getMessage("command-claiminfo-not-found");
COMMAND_CLAIMINFO_UUID_REQUIRED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminfo-uuid-required");
COMMAND_CLAIMINHERIT_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminherit-disabled");
COMMAND_CLAIMINHERIT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminherit-enabled");
COMMAND_CLAIMMODE_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-disabled");
COMMAND_CLAIMMODE_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-enabled");
COMMAND_CUBOID_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-disabled");
COMMAND_CUBOID_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-enabled");
COMMAND_INHERIT_ONLY_CHILD = MessageStorage.MESSAGE_DATA.getMessage("command-inherit-only-child");
COMMAND_INVALID = MessageStorage.MESSAGE_DATA.getMessage("command-invalid");
COMMAND_INVALID_PLAYER_GROUP = MessageStorage.MESSAGE_DATA.getMessage("command-invalid-player-group");
COMMAND_NOT_AVAILABLE_ECONOMY = MessageStorage.MESSAGE_DATA.getMessage("command-not-available-economy");
COMMAND_PET_CONFIRMATION = MessageStorage.MESSAGE_DATA.getMessage("command-pet-confirmation");
COMMAND_PET_TRANSFER_READY = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-ready");
COMMAND_PET_TRANSFER_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-cancel");
COMMAND_WORLDEDIT_MISSING = MessageStorage.MESSAGE_DATA.getMessage("command-worldedit-missing");
CREATE_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("create-cancel");
CREATE_CUBOID_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("create-cuboid-disabled");
CREATE_OVERLAP = MessageStorage.MESSAGE_DATA.getMessage("create-overlap");
CREATE_OVERLAP_SHORT = MessageStorage.MESSAGE_DATA.getMessage("create-overlap-short");
CREATE_SUBDIVISION_FAIL = MessageStorage.MESSAGE_DATA.getMessage("create-subdivision-fail");
CREATE_SUBDIVISION_ONLY = MessageStorage.MESSAGE_DATA.getMessage("create-subdivision-only");
DEBUG_NO_RECORDS = MessageStorage.MESSAGE_DATA.getMessage("debug-no-records");
DEBUG_PASTE_SUCCESS = MessageStorage.MESSAGE_DATA.getMessage("debug-paste-success");
DEBUG_RECORD_END = MessageStorage.MESSAGE_DATA.getMessage("debug-record-end");
DEBUG_RECORD_START = MessageStorage.MESSAGE_DATA.getMessage("debug-record-start");
DEBUG_TIME_ELAPSED = MessageStorage.MESSAGE_DATA.getMessage("debug-time-elapsed");
ECONOMY_BLOCK_BUY_INVALID = MessageStorage.MESSAGE_DATA.getMessage("economy-block-buy-invalid");
ECONOMY_BLOCK_BUY_SELL_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("economy-block-buy-sell-disabled");
ECONOMY_BLOCK_NOT_AVAILABLE = MessageStorage.MESSAGE_DATA.getMessage("economy-block-not-available");
ECONOMY_BLOCK_ONLY_BUY = MessageStorage.MESSAGE_DATA.getMessage("economy-block-only-buy");
ECONOMY_BLOCK_ONLY_SELL = MessageStorage.MESSAGE_DATA.getMessage("economy-block-only-sell");
ECONOMY_CLAIM_NOT_FOR_SALE = MessageStorage.MESSAGE_DATA.getMessage("economy-claim-not-for-sale");
ECONOMY_CLAIM_SALE_CANCELLED = MessageStorage.MESSAGE_DATA.getMessage("economy-claim-sale-cancelled");
ECONOMY_NOT_INSTALLED = MessageStorage.MESSAGE_DATA.getMessage("economy-not-installed");
ECONOMY_VIRTUAL_NOT_SUPPORTED = MessageStorage.MESSAGE_DATA.getMessage("economy-virtual-not-supported");
FEATURE_NOT_AVAILABLE = MessageStorage.MESSAGE_DATA.getMessage("feature-not-available");
FLAG_DESCRIPTION_CUSTOM_BLOCK_BREAK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-block-break");
FLAG_DESCRIPTION_CUSTOM_BLOCK_GROW = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-block-grow");
FLAG_DESCRIPTION_CUSTOM_BLOCK_PLACE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-block-place");
FLAG_DESCRIPTION_CUSTOM_BLOCK_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-block-spread");
FLAG_DESCRIPTION_CUSTOM_ENDERPEARL = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-enderpearl");
FLAG_DESCRIPTION_CUSTOM_EXIT_PLAYER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-exit-player");
FLAG_DESCRIPTION_CUSTOM_EXPLOSION_BLOCK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-explosion-block");
FLAG_DESCRIPTION_CUSTOM_EXPLOSION_ENTITY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-explosion-entity");
FLAG_DESCRIPTION_CUSTOM_EXP_DROP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-exp-drop");
FLAG_DESCRIPTION_CUSTOM_FALL_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-fall-damage");
FLAG_DESCRIPTION_CUSTOM_INTERACT_BLOCK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-interact-block");
FLAG_DESCRIPTION_CUSTOM_INTERACT_ENTITY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-interact-entity");
FLAG_DESCRIPTION_CUSTOM_INTERACT_INVENTORY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-interact-inventory");
FLAG_DESCRIPTION_CUSTOM_INVINCIBLE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-invincible");
FLAG_DESCRIPTION_CUSTOM_ITEM_DROP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-item-drop");
FLAG_DESCRIPTION_CUSTOM_ITEM_PICKUP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-item-pickup");
FLAG_DESCRIPTION_CUSTOM_MONSTER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-monster-damage");
FLAG_DESCRIPTION_CUSTOM_PISTONS = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-pistons");
FLAG_DESCRIPTION_CUSTOM_PORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-portal-use");
FLAG_DESCRIPTION_CUSTOM_SPAWN_AMBIENT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-spawn-ambient");
FLAG_DESCRIPTION_CUSTOM_SPAWN_ANIMAL = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-spawn-animal");
FLAG_DESCRIPTION_CUSTOM_SPAWN_AQUATIC = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-spawn-aquatic");
FLAG_DESCRIPTION_CUSTOM_SPAWN_MONSTER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-spawn-monster");
FLAG_DESCRIPTION_CUSTOM_TELEPORT_FROM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-teleport-from");
FLAG_DESCRIPTION_CUSTOM_TELEPORT_TO = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-teleport-to");
FLAG_DESCRIPTION_CUSTOM_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-use");
FLAG_DESCRIPTION_CUSTOM_VEHICLE_DESTROY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-vehicle-destroy");
FLAG_DESCRIPTION_CUSTOM_WITHER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-wither-damage");
FLAG_DESCRIPTION_CUSTOM_BLOCK_TRAMPLING = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-block-trampling");
FLAG_DESCRIPTION_CUSTOM_CHEST_ACCESS = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-chest-access");
FLAG_DESCRIPTION_CUSTOM_CHORUS_FRUIT_TELEPORT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-chorus-fruit-teleport");
FLAG_DESCRIPTION_CUSTOM_CROP_GROWTH = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-crop-growth");
FLAG_DESCRIPTION_CUSTOM_DAMAGE_ANIMALS = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-damage-animals");
FLAG_DESCRIPTION_CUSTOM_ENDERMAN_GRIEF = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-enderman-grief");
FLAG_DESCRIPTION_CUSTOM_ENTER_PLAYER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-enter-player");
FLAG_DESCRIPTION_CUSTOM_EXPLOSION_CREEPER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-explosion-creeper");
FLAG_DESCRIPTION_CUSTOM_EXPLOSION_TNT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-explosion-tnt");
FLAG_DESCRIPTION_CUSTOM_FIRE_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-fire-damage");
FLAG_DESCRIPTION_CUSTOM_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-fire-spread");
FLAG_DESCRIPTION_CUSTOM_GRASS_GROWTH = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-grass-growth");
FLAG_DESCRIPTION_CUSTOM_ICE_FORM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-ice-form");
FLAG_DESCRIPTION_CUSTOM_ICE_MELT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-ice-melt");
FLAG_DESCRIPTION_CUSTOM_LAVA_FLOW = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-lava-flow");
FLAG_DESCRIPTION_CUSTOM_LEAF_DECAY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-leaf-decay");
FLAG_DESCRIPTION_CUSTOM_LIGHTNING = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-lightning");
FLAG_DESCRIPTION_CUSTOM_LIGHTER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-lighter");
FLAG_DESCRIPTION_CUSTOM_MUSHROOM_GROWTH = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-mushroom-growth");
FLAG_DESCRIPTION_CUSTOM_MYCELIUM_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-mycelium-spread");
FLAG_DESCRIPTION_CUSTOM_PVP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-pvp");
FLAG_DESCRIPTION_CUSTOM_RIDE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-ride");
FLAG_DESCRIPTION_CUSTOM_SLEEP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-sleep");
FLAG_DESCRIPTION_CUSTOM_SNOW_FALL = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-snow-fall");
FLAG_DESCRIPTION_CUSTOM_SNOW_MELT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-snow-melt");
FLAG_DESCRIPTION_CUSTOM_SNOWMAN_TRAIL = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-snowman-trail");
FLAG_DESCRIPTION_CUSTOM_SOIL_DRY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-soil-dry");
FLAG_DESCRIPTION_CUSTOM_VEHICLE_PLACE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-vehicle-place");
FLAG_DESCRIPTION_CUSTOM_VINE_GROWTH = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-vine-growth");
FLAG_DESCRIPTION_CUSTOM_WATER_FLOW = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-water-flow");
FLAG_DESCRIPTION_BLOCK_BREAK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-break");
FLAG_DESCRIPTION_BLOCK_GROW = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-grow");
FLAG_DESCRIPTION_BLOCK_MODIFY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-modify");
FLAG_DESCRIPTION_BLOCK_PLACE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-place");
FLAG_DESCRIPTION_BLOCK_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-spread");
FLAG_DESCRIPTION_COLLIDE_BLOCK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-collide-block");
FLAG_DESCRIPTION_COLLIDE_ENTITY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-collide-entity");
FLAG_DESCRIPTION_COMMAND_EXECUTE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-command-execute");
FLAG_DESCRIPTION_COMMAND_EXECUTE_PVP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-command-execute-pvp");
FLAG_DESCRIPTION_ENTER_CLAIM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-enter-claim");
FLAG_DESCRIPTION_ENTITY_CHUNK_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-chunk-spawn");
FLAG_DESCRIPTION_ENTITY_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-damage");
FLAG_DESCRIPTION_ENTITY_RIDING = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-riding");
FLAG_DESCRIPTION_ENTITY_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-spawn");
FLAG_DESCRIPTION_ENTITY_TELEPORT_FROM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-teleport-from");
FLAG_DESCRIPTION_ENTITY_TELEPORT_TO = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-teleport-to");
FLAG_DESCRIPTION_EXIT_CLAIM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-exit-claim");
FLAG_DESCRIPTION_EXPLOSION_BLOCK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-explosion-block");
FLAG_DESCRIPTION_EXPLOSION_ENTITY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-explosion-entity");
FLAG_DESCRIPTION_INTERACT_BLOCK_PRIMARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-primary");
FLAG_DESCRIPTION_INTERACT_BLOCK_SECONDARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-block-secondary");
FLAG_DESCRIPTION_INTERACT_ENTITY_PRIMARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-primary");
FLAG_DESCRIPTION_INTERACT_ENTITY_SECONDARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-entity-secondary");
FLAG_DESCRIPTION_INTERACT_ITEM_PRIMARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-interact-item-primary");
FLAG_DESCRIPTION_INTERACT_ITEM_SECONDARY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-interact-item-secondary");
FLAG_DESCRIPTION_INTERACT_INVENTORY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-interact-inventory");
FLAG_DESCRIPTION_INTERACT_INVENTORY_CLICK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-interact-inventory-click");
FLAG_DESCRIPTION_ITEM_DROP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-item-drop");
FLAG_DESCRIPTION_ITEM_PICKUP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-item-pickup");
FLAG_DESCRIPTION_ITEM_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("flag-description-item-spawn");
FLAG_DESCRIPTION_ITEM_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-item-use");
FLAG_DESCRIPTION_LEAF_DECAY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-leaf-decay");
FLAG_DESCRIPTION_LIQUID_FLOW = MessageStorage.MESSAGE_DATA.getMessage("flag-description-liquid-flow");
FLAG_DESCRIPTION_PORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-portal-use");
FLAG_DESCRIPTION_PROJECTILE_IMPACT_BLOCK = MessageStorage.MESSAGE_DATA.getMessage("flag-description-projectile-impact-block");
FLAG_DESCRIPTION_PROJECTILE_IMPACT_ENTITY = MessageStorage.MESSAGE_DATA.getMessage("flag-description-projectile-impact-entity");
FLAG_RESET_SUCCESS = MessageStorage.MESSAGE_DATA.getMessage("flag-reset-success");
FLAG_RESET_WARNING = MessageStorage.MESSAGE_DATA.getMessage("flag-reset-warning");
FLAG_UI_CLICK_ALLOW = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-click-allow");
FLAG_UI_CLICK_DENY = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-click-deny");
FLAG_UI_CLICK_REMOVE = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-click-remove");
FLAG_UI_INFO_CLAIM = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-info-claim");
FLAG_UI_INFO_DEFAULT = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-info-default");
FLAG_UI_INFO_INHERIT = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-info-inherit");
FLAG_UI_INFO_OVERRIDE = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-info-override");
FLAG_UI_OVERRIDE_NO_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-override-no-permission");
FLAG_UI_RETURN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-return-flags");
LABEL_ACCESSORS = MessageStorage.MESSAGE_DATA.getMessage("label-accessors");
LABEL_AREA = MessageStorage.MESSAGE_DATA.getMessage("label-area");
LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks");
LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders");
LABEL_BUY = MessageStorage.MESSAGE_DATA.getMessage("label-buy");
LABEL_CHILDREN = MessageStorage.MESSAGE_DATA.getMessage("label-children");
LABEL_CONFIRM = MessageStorage.MESSAGE_DATA.getMessage("label-confirm");
LABEL_CONTAINERS = MessageStorage.MESSAGE_DATA.getMessage("label-containers");
LABEL_CONTEXT = MessageStorage.MESSAGE_DATA.getMessage("label-context");
LABEL_CREATED = MessageStorage.MESSAGE_DATA.getMessage("label-created");
LABEL_DISPLAYING = MessageStorage.MESSAGE_DATA.getMessage("label-displaying");
LABEL_EXPIRED = MessageStorage.MESSAGE_DATA.getMessage("label-expired");
LABEL_FAREWELL = MessageStorage.MESSAGE_DATA.getMessage("label-farewell");
LABEL_FLAG = MessageStorage.MESSAGE_DATA.getMessage("label-flag");
LABEL_GREETING = MessageStorage.MESSAGE_DATA.getMessage("label-greeting");
LABEL_GROUP = MessageStorage.MESSAGE_DATA.getMessage("label-group");
LABEL_INHERIT = MessageStorage.MESSAGE_DATA.getMessage("label-inherit");
LABEL_LOCATION = MessageStorage.MESSAGE_DATA.getMessage("label-location");
LABEL_MANAGERS = MessageStorage.MESSAGE_DATA.getMessage("label-managers");
LABEL_NAME = MessageStorage.MESSAGE_DATA.getMessage("label-name");
LABEL_NO = MessageStorage.MESSAGE_DATA.getMessage("label-no");
LABEL_OUTPUT = MessageStorage.MESSAGE_DATA.getMessage("label-output");
LABEL_OWNER = MessageStorage.MESSAGE_DATA.getMessage("label-owner");
LABEL_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("label-permission");
LABEL_PLAYER = MessageStorage.MESSAGE_DATA.getMessage("label-player");
LABEL_PRICE = MessageStorage.MESSAGE_DATA.getMessage("label-price");
LABEL_RAID = MessageStorage.MESSAGE_DATA.getMessage("label-raid");
LABEL_RESIZABLE = MessageStorage.MESSAGE_DATA.getMessage("label-resizable");
LABEL_RESULT = MessageStorage.MESSAGE_DATA.getMessage("label-result");
LABEL_SCHEMATIC = MessageStorage.MESSAGE_DATA.getMessage("label-schematic");
LABEL_SOURCE = MessageStorage.MESSAGE_DATA.getMessage("label-source");
LABEL_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("label-spawn");
LABEL_TARGET = MessageStorage.MESSAGE_DATA.getMessage("label-target");
LABEL_TRUST = MessageStorage.MESSAGE_DATA.getMessage("label-trust");
LABEL_TYPE = MessageStorage.MESSAGE_DATA.getMessage("label-type");
LABEL_UNKNOWN = MessageStorage.MESSAGE_DATA.getMessage("label-unknown");
LABEL_USER = MessageStorage.MESSAGE_DATA.getMessage("label-user");
LABEL_WORLD = MessageStorage.MESSAGE_DATA.getMessage("label-world");
LABEL_YES = MessageStorage.MESSAGE_DATA.getMessage("label-yes");
MODE_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("mode-admin");
MODE_BASIC = MessageStorage.MESSAGE_DATA.getMessage("mode-basic");
MODE_NATURE = MessageStorage.MESSAGE_DATA.getMessage("mode-nature");
MODE_SUBDIVISION = MessageStorage.MESSAGE_DATA.getMessage("mode-subdivision");
MODE_TOWN = MessageStorage.MESSAGE_DATA.getMessage("mode-town");
OPTION_DESCRIPTION_ABANDON_DELAY = MessageStorage.MESSAGE_DATA.getMessage("option-description-abandon-delay");
OPTION_DESCRIPTION_ABANDON_RETURN_RATIO = MessageStorage.MESSAGE_DATA.getMessage("option-description-abandon-return-ratio");
OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR = MessageStorage.MESSAGE_DATA.getMessage("option-description-blocks-accrued-per-hour");
OPTION_DESCRIPTION_CHEST_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-chest-expiration");
OPTION_DESCRIPTION_CREATE_LIMIT = MessageStorage.MESSAGE_DATA.getMessage("option-description-create-limit");
OPTION_DESCRIPTION_CREATE_MODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-create-mode");
OPTION_DESCRIPTION_ECONOMY_BLOCK_COST = MessageStorage.MESSAGE_DATA.getMessage("option-description-economy-block-cost");
OPTION_DESCRIPTION_ECONOMY_BLOCK_SELL_RETURN = MessageStorage.MESSAGE_DATA.getMessage("option-description-economy-block-sell-return");
OPTION_DESCRIPTION_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-expiration");
OPTION_DESCRIPTION_INITIAL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("option-description-initial-blocks");
OPTION_DESCRIPTION_MAX_ACCRUED_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("option-description-max-accrued-blocks");
OPTION_DESCRIPTION_MAX_LEVEL = MessageStorage.MESSAGE_DATA.getMessage("option-description-max-level");
OPTION_DESCRIPTION_MAX_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-max-size-x");
OPTION_DESCRIPTION_MAX_SIZE_Y = MessageStorage.MESSAGE_DATA.getMessage("option-description-max-size-y");
OPTION_DESCRIPTION_MAX_SIZE_Z = MessageStorage.MESSAGE_DATA.getMessage("option-description-max-size-z");
OPTION_DESCRIPTION_MIN_LEVEL = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-level");
OPTION_DESCRIPTION_MIN_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-x");
OPTION_DESCRIPTION_MIN_SIZE_Y = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-y");
OPTION_DESCRIPTION_MIN_SIZE_Z = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-z");
OPTION_DESCRIPTION_PLAYER_COMMAND = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command");
OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-flight");
OPTION_DESCRIPTION_PLAYER_DENY_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-godmode");
OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger");
OPTION_DESCRIPTION_PLAYER_GAMEMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-gamemode");
OPTION_DESCRIPTION_PLAYER_HEALTH_REGEN = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-health-regen");
OPTION_DESCRIPTION_PLAYER_KEEP_INVENTORY = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-keep-inventory");
OPTION_DESCRIPTION_PLAYER_KEEP_LEVEL = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-keep-level");
OPTION_DESCRIPTION_PLAYER_WALK_SPEED = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-walk-speed");
OPTION_DESCRIPTION_PLAYER_WEATHER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-weather");
OPTION_DESCRIPTION_RADIUS_LIST = MessageStorage.MESSAGE_DATA.getMessage("option-description-radius-list");
OPTION_DESCRIPTION_RADIUS_INSPECT = MessageStorage.MESSAGE_DATA.getMessage("option-description-radius-inspect");
OPTION_DESCRIPTION_TAX_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration");
OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration-days-keep");
OPTION_DESCRIPTION_TAX_RATE = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-rate");
OPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-player-deny-flight");
OWNER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("owner-admin");
PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having");
PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create");
PERMISSION_CLAIM_ENTER = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-enter");
PERMISSION_CLAIM_EXIT = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-exit");
PERMISSION_CLAIM_LIST = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-list");
PERMISSION_CLAIM_RESET_FLAGS_SELF = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-reset-flags-self");
PERMISSION_CLAIM_RESIZE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-resize");
PERMISSION_CLAIM_SALE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-sale");
PERMISSION_CLAIM_TRANSFER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-transfer-admin");
PERMISSION_CLEAR = MessageStorage.MESSAGE_DATA.getMessage("permission-clear");
PERMISSION_CLEAR_ALL = MessageStorage.MESSAGE_DATA.getMessage("permission-clear-all");
PERMISSION_COMMAND_TRUST = MessageStorage.MESSAGE_DATA.getMessage("permission-command-trust");
PERMISSION_CUBOID = MessageStorage.MESSAGE_DATA.getMessage("permission-cuboid");
PERMISSION_EDIT_CLAIM = MessageStorage.MESSAGE_DATA.getMessage("permission-edit-claim");
PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread");
PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults");
PERMISSION_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-overrides");
PERMISSION_FLAG_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-use");
PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid");
PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option");
PERMISSION_GRANT = MessageStorage.MESSAGE_DATA.getMessage("permission-grant");
PERMISSION_GROUP_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-group-option");
PERMISSION_OPTION_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-option-defaults");
PERMISSION_OPTION_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-option-overrides");
PERMISSION_OPTION_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-option-use");
PERMISSION_OVERRIDE_DENY = MessageStorage.MESSAGE_DATA.getMessage("permission-override-deny");
PERMISSION_PLAYER_ADMIN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("permission-player-admin-flags");
PERMISSION_PLAYER_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-player-option");
PERMISSION_PLAYER_VIEW_OTHERS = MessageStorage.MESSAGE_DATA.getMessage("permission-player-view-others");
PERMISSION_VISUAL_CLAIMS_NEARBY = MessageStorage.MESSAGE_DATA.getMessage("permission-visual-claims-nearby");
PLAYERINFO_UI_TITLE = MessageStorage.MESSAGE_DATA.getMessage("playerinfo-ui-title");
PLUGIN_EVENT_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("plugin-event-cancel");
PLUGIN_RELOAD = MessageStorage.MESSAGE_DATA.getMessage("plugin-reload");
PVP_CLAIM_NOT_ALLOWED = MessageStorage.MESSAGE_DATA.getMessage("pvp-claim-not-allowed");
PVP_SOURCE_NOT_ALLOWED = MessageStorage.MESSAGE_DATA.getMessage("pvp-source-not-allowed");
PVP_TARGET_NOT_ALLOWED = MessageStorage.MESSAGE_DATA.getMessage("pvp-target-not-allowed");
RESIZE_OVERLAP = MessageStorage.MESSAGE_DATA.getMessage("resize-overlap");
RESIZE_OVERLAP_SUBDIVISION = MessageStorage.MESSAGE_DATA.getMessage("resize-overlap-subdivision");
RESIZE_SAME_LOCATION = MessageStorage.MESSAGE_DATA.getMessage("resize-same-location");
RESIZE_START = MessageStorage.MESSAGE_DATA.getMessage("resize-start");
SCHEMATIC_ABANDON_ALL_RESTORE_WARNING = MessageStorage.MESSAGE_DATA.getMessage("schematic-abandon-all-restore-warning");
SCHEMATIC_ABANDON_RESTORE_WARNING = MessageStorage.MESSAGE_DATA.getMessage("schematic-abandon-restore-warning");
SCHEMATIC_CREATE = MessageStorage.MESSAGE_DATA.getMessage("schematic-create");
SCHEMATIC_CREATE_COMPLETE = MessageStorage.MESSAGE_DATA.getMessage("schematic-create-complete");
SCHEMATIC_CREATE_FAIL = MessageStorage.MESSAGE_DATA.getMessage("schematic-create-fail");
SCHEMATIC_NONE = MessageStorage.MESSAGE_DATA.getMessage("schematic-none");
SPAWN_NOT_SET = MessageStorage.MESSAGE_DATA.getMessage("spawn-not-set");
TELEPORT_MOVE_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("teleport-move-cancel");
TELEPORT_NO_SAFE_LOCATION = MessageStorage.MESSAGE_DATA.getMessage("teleport-no-safe-location");
TITLE_ACCESSOR = MessageStorage.MESSAGE_DATA.getMessage("title-accessor");
TITLE_ALL = MessageStorage.MESSAGE_DATA.getMessage("title-all");
TITLE_BUILDER = MessageStorage.MESSAGE_DATA.getMessage("title-builder");
TITLE_CLAIM = MessageStorage.MESSAGE_DATA.getMessage("title-claim");
TITLE_CONTAINER = MessageStorage.MESSAGE_DATA.getMessage("title-container");
TITLE_DEFAULT = MessageStorage.MESSAGE_DATA.getMessage("title-default");
TITLE_INHERIT = MessageStorage.MESSAGE_DATA.getMessage("title-inherit");
TITLE_MANAGER = MessageStorage.MESSAGE_DATA.getMessage("title-manager");
TITLE_OWN = MessageStorage.MESSAGE_DATA.getMessage("title-own");
TITLE_OVERRIDE = MessageStorage.MESSAGE_DATA.getMessage("title-override");
TOWN_CHAT_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("town-chat-disabled");
TOWN_CHAT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("town-chat-enabled");
TOWN_NOT_FOUND = MessageStorage.MESSAGE_DATA.getMessage("town-not-found");
TOWN_NOT_IN = MessageStorage.MESSAGE_DATA.getMessage("town-not-in");
TOWN_OWNER = MessageStorage.MESSAGE_DATA.getMessage("town-owner");
TOWN_TAG_CLEAR = MessageStorage.MESSAGE_DATA.getMessage("town-tag-clear");
TOWN_TAX_NO_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("town-tax-no-claims");
TRUST_CLICK_SHOW_LIST = MessageStorage.MESSAGE_DATA.getMessage("trust-click-show-list");
TRUST_INVALID = MessageStorage.MESSAGE_DATA.getMessage("trust-invalid");
TRUST_LIST_HEADER = MessageStorage.MESSAGE_DATA.getMessage("trust-list-header");
TRUST_NO_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("trust-no-claims");
TRUST_SELF = MessageStorage.MESSAGE_DATA.getMessage("trust-self");
UI_CLICK_CONFIRM = MessageStorage.MESSAGE_DATA.getMessage("ui-click-confirm");
UNTRUST_NO_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("untrust-no-claims");
UNTRUST_SELF = MessageStorage.MESSAGE_DATA.getMessage("untrust-self");
// reload Flag/Option caches
for (Option option : OptionRegistryModule.getInstance().getAll()) {
((GDOption) option).reloadDescription();
}
for (Flag flag : FlagRegistryModule.getInstance().getAll()) {
((GDFlag) flag).reloadDescription();
}
}
}

View File

@ -0,0 +1,154 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.cache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.util.PermissionUtil;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.user.UserStorageService;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class PermissionHolderCache {
private static PermissionHolderCache instance;
private final Cache<UUID, GDPermissionUser> userCache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
private final Cache<String, GDPermissionGroup> groupCache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
private final ConcurrentHashMap<GDPermissionHolder, Cache<Integer, Tristate>> permissionCache = new ConcurrentHashMap<>();
public GDPermissionUser getOrCreateUser(User user) {
if (user == null) {
return null;
}
return this.getOrCreateUser(user.getUniqueId());
}
public GDPermissionUser getOrCreateUser(UUID uuid) {
if (uuid == null) {
return null;
}
if (uuid.equals(GriefDefenderPlugin.PUBLIC_UUID)) {
return GriefDefenderPlugin.PUBLIC_USER;
}
if (uuid.equals(GriefDefenderPlugin.WORLD_USER_UUID)) {
return GriefDefenderPlugin.WORLD_USER;
}
GDPermissionUser holder = this.userCache.getIfPresent(uuid);
if (holder != null) {
return holder;
}
holder = new GDPermissionUser(uuid);
this.userCache.put(uuid, holder);
return holder;
}
public GDPermissionUser getOrCreateUser(String username) {
if (username == null) {
return null;
}
final UUID uuid = PermissionUtil.getInstance().lookupUserUniqueId(username);
if (uuid != null) {
return this.getOrCreateUser(uuid);
}
User user = Sponge.getGame().getServiceManager().provide(UserStorageService.class).get().get(username).orElse(null);
if (user == null) {
user = NMSUtil.getInstance().createUserFromCache(username);
}
if (user != null) {
return this.getOrCreateUser(user);
}
return null;
}
public GDPermissionGroup getOrCreateGroup(String groupName) {
if (groupName == null) {
return null;
}
GDPermissionGroup holder = this.groupCache.getIfPresent(groupName);
if (holder != null) {
return holder;
}
holder = new GDPermissionGroup(groupName);
this.groupCache.put(groupName, holder);
return holder;
}
public GDPermissionHolder getOrCreateHolder(String identifier) {
if (identifier == null) {
return null;
}
UUID uuid = null;
try {
uuid = UUID.fromString(identifier);
} catch (IllegalArgumentException e) {
return this.getOrCreateGroup(identifier);
}
return this.getOrCreateUser(uuid);
}
public Cache<Integer, Tristate> getOrCreatePermissionCache(GDPermissionHolder holder) {
Cache<Integer, Tristate> cache = this.permissionCache.get(holder);
if (cache == null) {
cache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build();
this.permissionCache.put(holder, cache);
}
return cache;
}
public void invalidateAllPermissionCache() {
for (Cache<Integer, Tristate> cache : this.permissionCache.values()) {
cache.invalidateAll();
}
}
static {
instance = new PermissionHolderCache();
}
public static PermissionHolderCache getInstance() {
return instance;
}
}

View File

@ -0,0 +1,87 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.context.ContextCalculator;
import org.spongepowered.api.service.permission.Subject;
import java.util.Set;
import java.util.UUID;
public class ClaimContextCalculator implements ContextCalculator<Subject> {
@Override
public void accumulateContexts(Subject calculable, Set<Context> accumulator) {
if (calculable.getCommandSource().isPresent() && calculable.getCommandSource().get() instanceof Player) {
Player player = (Player) calculable.getCommandSource().get();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());
if (playerData == null) {
return;
}
if (playerData.ignoreActiveContexts) {
playerData.ignoreActiveContexts = false;
return;
}
GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (sourceClaim != null) {
if (playerData == null || playerData.canIgnoreClaim(sourceClaim)) {
return;
}
if (sourceClaim.parent != null && sourceClaim.getData().doesInheritParent()) {
accumulator.add(sourceClaim.parent.getSpongeContext());
} else {
accumulator.add(sourceClaim.getSpongeContext());
}
}
}
}
@Override
public boolean matches(Context context, Subject subject) {
if (context.equals("gd_claim")) {
if (subject.getCommandSource().isPresent() && subject.getCommandSource().get() instanceof Player) {
Player player = (Player) subject.getCommandSource().get();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());
if (playerData == null) {
return false;
}
GDClaim playerClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (playerClaim != null && playerClaim.getUniqueId().equals(UUID.fromString(context.getValue()))) {
return true;
}
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,668 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.api.claim.ClaimManager;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.configuration.ClaimDataConfig;
import com.griefdefender.configuration.ClaimStorageData;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.PlayerStorageData;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.storage.BaseStorage;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.service.economy.EconomyService;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.account.UniqueAccount;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
public class GDClaimManager implements ClaimManager {
private static final BaseStorage DATASTORE = GriefDefenderPlugin.getInstance().dataStore;
private UUID worldUniqueId;
private GriefDefenderConfig<?> activeConfig;
// Player UUID -> player data
private Map<UUID, GDPlayerData> playerDataList = Maps.newHashMap();
// World claim list
private Set<Claim> worldClaims = new HashSet<>();
// Claim UUID -> Claim
private Map<UUID, Claim> claimUniqueIdMap = Maps.newHashMap();
// String -> Claim
private Map<Long, Set<Claim>> chunksToClaimsMap = new Long2ObjectOpenHashMap<>(4096);
private GDClaim theWildernessClaim;
public GDClaimManager(World world) {
this.worldUniqueId = world.getUniqueId();
this.activeConfig = GriefDefenderPlugin.getActiveConfig(this.worldUniqueId);
}
public GDPlayerData getOrCreatePlayerData(UUID playerUniqueId) {
GDPlayerData playerData = this.getPlayerDataMap().get(playerUniqueId);
if (playerData == null) {
return createPlayerData(playerUniqueId);
} else {
return playerData;
}
}
private GDPlayerData createPlayerData(UUID playerUniqueId) {
Path playerFilePath = null;
if (BaseStorage.USE_GLOBAL_PLAYER_STORAGE) {
playerFilePath = BaseStorage.globalPlayerDataPath.resolve(playerUniqueId.toString());
} else {
playerFilePath = BaseStorage.worldConfigMap.get(this.worldUniqueId).getPath().getParent().resolve("PlayerData").resolve(playerUniqueId.toString());
}
PlayerStorageData playerStorage = new PlayerStorageData(playerFilePath);
Set<Claim> claimList = this.createPlayerClaimList(playerUniqueId);
GDPlayerData playerData = new GDPlayerData(this.worldUniqueId, playerUniqueId, playerStorage, this.activeConfig, claimList);
this.getPlayerDataMap().put(playerUniqueId, playerData);
return playerData;
}
private Set<Claim> createPlayerClaimList(UUID playerUniqueId) {
Set<Claim> claimList = new HashSet<>();
if (BaseStorage.USE_GLOBAL_PLAYER_STORAGE) {
for (World world : Sponge.getServer().getWorlds()) {
GDClaimManager claimmanager = DATASTORE.getClaimWorldManager(world.getUniqueId());
for (Claim claim : claimmanager.worldClaims) {
GDClaim gpClaim = (GDClaim) claim;
if (gpClaim.isAdminClaim()) {
continue;
}
if (gpClaim.parent != null) {
if (gpClaim.parent.getOwnerUniqueId().equals(playerUniqueId)) {
claimList.add(claim);
}
} else {
if (gpClaim.getOwnerUniqueId().equals(playerUniqueId)) {
claimList.add(claim);
}
}
}
}
} else {
for (Claim claim : this.worldClaims) {
GDClaim gpClaim = (GDClaim) claim;
if (gpClaim.isAdminClaim()) {
continue;
}
if (gpClaim.parent != null) {
if (gpClaim.parent.getOwnerUniqueId().equals(playerUniqueId)) {
claimList.add(claim);
}
} else {
if (gpClaim.getOwnerUniqueId().equals(playerUniqueId)) {
claimList.add(claim);
}
}
}
}
return claimList;
}
public void removePlayer(UUID playerUniqueId) {
this.getPlayerDataMap().remove(playerUniqueId);
}
public ClaimResult addClaim(Claim claim) {
GDClaim newClaim = (GDClaim) claim;
// ensure this new claim won't overlap any existing claims
ClaimResult result = newClaim.checkArea(false);
if (!result.successful()) {
return result;
}
// validate world
if (!this.worldUniqueId.equals(newClaim.getWorld().getUniqueId())) {
World world = Sponge.getServer().getWorld(this.worldUniqueId).get();
newClaim.setWorld(world);
}
// otherwise add this new claim to the data store to make it effective
this.addClaim(newClaim, true);
if (result.getClaims().size() > 1) {
newClaim.migrateClaims(new ArrayList<>(result.getClaims()));
}
return result;
}
public void addClaim(Claim claimToAdd, boolean writeToStorage) {
GDClaim claim = (GDClaim) claimToAdd;
if (claim.parent == null && this.worldClaims.contains(claimToAdd)) {
return;
}
if (writeToStorage) {
DATASTORE.writeClaimToStorage(claim);
}
// We need to keep track of all claims so they can be referenced by children during server startup
this.claimUniqueIdMap.put(claim.getUniqueId(), claim);
if (claim.isWilderness()) {
this.theWildernessClaim = claim;
return;
}
if (claim.parent != null) {
claim.parent.children.add(claim);
this.worldClaims.remove(claim);
this.deleteChunkHashes((GDClaim) claim);
if (!claim.isAdminClaim() && (!claim.isInTown() || !claim.getTownClaim().getOwnerUniqueId().equals(claim.getOwnerUniqueId()))) {
final GDPlayerData playerData = this.getPlayerDataMap().get(claim.getOwnerUniqueId());
Set<Claim> playerClaims = playerData.getInternalClaims();
if (!playerClaims.contains(claim)) {
playerClaims.add(claim);
}
}
return;
}
if (!this.worldClaims.contains(claim)) {
this.worldClaims.add(claim);
}
final UUID ownerId = claim.getOwnerUniqueId();
final GDPlayerData playerData = this.getPlayerDataMap().get(ownerId);
if (playerData != null) {
Set<Claim> playerClaims = playerData.getInternalClaims();
if (!playerClaims.contains(claim)) {
playerClaims.add(claim);
}
} else if (!claim.isAdminClaim()) {
this.createPlayerData(ownerId);
}
this.updateChunkHashes(claim);
return;
}
public void updateChunkHashes(GDClaim claim) {
this.deleteChunkHashes(claim);
Set<Long> chunkHashes = claim.getChunkHashes(true);
for (Long chunkHash : chunkHashes) {
Set<Claim> claimsInChunk = this.getInternalChunksToClaimsMap().get(chunkHash);
if (claimsInChunk == null) {
claimsInChunk = new HashSet<Claim>();
this.getInternalChunksToClaimsMap().put(chunkHash, claimsInChunk);
}
claimsInChunk.add(claim);
}
}
// Used when parent claims becomes children
public void removeClaimData(Claim claim) {
this.worldClaims.remove(claim);
this.deleteChunkHashes((GDClaim) claim);
}
@Override
public ClaimResult deleteClaim(Claim claim, boolean deleteChildren) {
GDRemoveClaimEvent event = new GDRemoveClaimEvent(claim);
GriefDefender.getEventManager().post(event);
if (event.cancelled()) {
return new GDClaimResult(claim, ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
}
return this.deleteClaimInternal(claim, deleteChildren);
}
public ClaimResult deleteClaimInternal(Claim claim, boolean deleteChildren) {
final GDClaim gpClaim = (GDClaim) claim;
Set<Claim> subClaims = claim.getChildren(false);
for (Claim child : subClaims) {
if (deleteChildren || (gpClaim.parent == null && child.isSubdivision())) {
this.deleteClaimInternal(child, true);
continue;
}
final GDClaim parentClaim = (GDClaim) claim;
final GDClaim childClaim = (GDClaim) child;
if (parentClaim.parent != null) {
migrateChildToNewParent(parentClaim.parent, childClaim);
} else {
// move child to parent folder
migrateChildToNewParent(null, childClaim);
}
}
resetPlayerClaimVisuals(claim);
// transfer bank balance to owner
final Account bankAccount = ((GDClaim) claim).getEconomyAccount();
if (bankAccount != null) {
try (final CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(GriefDefenderPlugin.getInstance());
final EconomyService economyService = GriefDefenderPlugin.getInstance().economyService.get();
final UniqueAccount ownerAccount = economyService.getOrCreateAccount(claim.getOwnerUniqueId()).orElse(null);
if (ownerAccount != null) {
ownerAccount.deposit(economyService.getDefaultCurrency(), bankAccount.getBalance(economyService.getDefaultCurrency()),
Sponge.getCauseStackManager().getCurrentCause());
}
bankAccount.resetBalance(economyService.getDefaultCurrency(), Sponge.getCauseStackManager().getCurrentCause());
}
}
this.worldClaims.remove(claim);
this.claimUniqueIdMap.remove(claim.getUniqueId());
this.deleteChunkHashes((GDClaim) claim);
if (gpClaim.parent != null) {
gpClaim.parent.children.remove(claim);
}
return DATASTORE.deleteClaimFromStorage((GDClaim) claim);
}
// Migrates children to new parent
private void migrateChildToNewParent(GDClaim parentClaim, GDClaim childClaim) {
childClaim.parent = parentClaim;
String fileName = childClaim.getClaimStorage().filePath.getFileName().toString();
Path newPath = null;
if (parentClaim == null) {
newPath = childClaim.getClaimStorage().folderPath.getParent().getParent().resolve(childClaim.getType().getName().toLowerCase()).resolve(fileName);
} else {
// Only store in same claim type folder if not admin.
// Admin claims are currently the only type that can hold children of same type within
if (childClaim.getType().equals(parentClaim.getType()) && (!parentClaim.isAdminClaim())) {
newPath = parentClaim.getClaimStorage().folderPath.resolve(fileName);
} else {
newPath = parentClaim.getClaimStorage().folderPath.resolve(childClaim.getType().getName().toLowerCase()).resolve(fileName);
}
}
try {
if (Files.notExists(newPath.getParent())) {
Files.createDirectories(newPath.getParent());
}
Files.move(childClaim.getClaimStorage().filePath, newPath);
if (childClaim.getClaimStorage().folderPath.toFile().listFiles().length == 0) {
Files.delete(childClaim.getClaimStorage().folderPath);
}
childClaim.setClaimStorage(new ClaimStorageData(newPath, this.worldUniqueId, (ClaimDataConfig) childClaim.getInternalClaimData()));
} catch (IOException e) {
e.printStackTrace();
}
// Make sure to update new parent in storage
final UUID parentUniqueId = parentClaim == null ? null : parentClaim.getUniqueId();
childClaim.getInternalClaimData().setParent(parentUniqueId);
this.addClaim(childClaim, true);
for (Claim child : childClaim.children) {
migrateChildToNewParent(childClaim, (GDClaim) child);
}
}
private void resetPlayerClaimVisuals(Claim claim) {
// player may be offline so check is needed
GDPlayerData playerData = this.getPlayerDataMap().get(claim.getOwnerUniqueId());
if (playerData != null) {
playerData.getInternalClaims().remove(claim);
if (playerData.lastClaim != null) {
playerData.lastClaim.clear();
}
}
// revert visuals for all players watching this claim
List<UUID> playersWatching = new ArrayList<>(((GDClaim) claim).playersWatching);
for (UUID playerUniqueId : playersWatching) {
Player player = Sponge.getServer().getPlayer(playerUniqueId).orElse(null);
if (player != null) {
playerData = this.getOrCreatePlayerData(playerUniqueId);
playerData.revertActiveVisual(player);
if (playerData.lastClaim != null) {
playerData.lastClaim.clear();
}
if (GriefDefenderPlugin.getInstance().worldEditProvider != null) {
GriefDefenderPlugin.getInstance().worldEditProvider.revertVisuals(player, playerData, claim.getUniqueId());
}
}
}
}
private void deleteChunkHashes(GDClaim claim) {
Set<Long> chunkHashes = claim.getChunkHashes(false);
if (chunkHashes == null) {
return;
}
for (Long chunkHash : chunkHashes) {
Set<Claim> claimsInChunk = this.getInternalChunksToClaimsMap().get(chunkHash);
if (claimsInChunk != null) {
claimsInChunk.remove(claim);
}
}
}
@Nullable
public Optional<Claim> getClaimByUUID(UUID claimUniqueId) {
return Optional.ofNullable(this.claimUniqueIdMap.get(claimUniqueId));
}
public Set<Claim> getInternalPlayerClaims(UUID playerUniqueId) {
final GDPlayerData playerData = this.getPlayerDataMap().get(playerUniqueId);
if (playerData == null) {
return new HashSet<>();
}
return playerData.getInternalClaims();
}
@Nullable
public Set<Claim> getPlayerClaims(UUID playerUniqueId) {
final GDPlayerData playerData = this.getPlayerDataMap().get(playerUniqueId);
if (playerData == null) {
return ImmutableSet.of();
}
return ImmutableSet.copyOf(this.getPlayerDataMap().get(playerUniqueId).getInternalClaims());
}
public void createWildernessClaim(World world) {
if (this.theWildernessClaim != null) {
return;
}
final Vector3i lesserCorner = new Vector3i(-30000000, 0, -30000000);
final Vector3i greaterCorner = new Vector3i(29999999, 255, 29999999);
// Use world UUID as wilderness claim ID
GDClaim wilderness = new GDClaim(world, lesserCorner, greaterCorner, world.getUniqueId(), ClaimTypes.WILDERNESS, null, false);
wilderness.setOwnerUniqueId(GriefDefenderPlugin.WORLD_USER_UUID);
wilderness.initializeClaimData(null);
wilderness.claimData.save();
wilderness.claimStorage.save();
this.theWildernessClaim = wilderness;
this.claimUniqueIdMap.put(wilderness.getUniqueId(), wilderness);
}
@Override
public GDClaim getWildernessClaim() {
if (this.theWildernessClaim == null) {
World world = Sponge.getServer().getWorld(this.worldUniqueId).get();
this.createWildernessClaim(world);
}
return this.theWildernessClaim;
}
@Override
public Set<Claim> getWorldClaims() {
return this.worldClaims;
}
public Map<UUID, GDPlayerData> getPlayerDataMap() {
if (BaseStorage.USE_GLOBAL_PLAYER_STORAGE) {
return BaseStorage.GLOBAL_PLAYER_DATA;
}
return this.playerDataList;
}
public Set<Claim> findOverlappingClaims(Claim claim) {
Set<Claim> claimSet = new HashSet<>();
for (Long chunkHash : claim.getChunkHashes()) {
final Set<Claim> chunkClaims = this.chunksToClaimsMap.get(chunkHash);
if (chunkClaims == null) {
continue;
}
for (Claim chunkClaim : chunkClaims) {
if (!chunkClaim.equals(claim) && (claim.overlaps(chunkClaim) || chunkClaim.overlaps(claim))) {
claimSet.add(chunkClaim);
}
}
}
return claimSet;
}
@Override
public Map<Long, Set<Claim>> getChunksToClaimsMap() {
return ImmutableMap.copyOf(this.chunksToClaimsMap);
}
public Map<Long, Set<Claim>> getInternalChunksToClaimsMap() {
return this.chunksToClaimsMap;
}
public void save() {
for (Claim claim : this.worldClaims) {
GDClaim gpClaim = (GDClaim) claim;
gpClaim.save();
}
this.getWildernessClaim().save();
for (GDPlayerData playerData : this.getPlayerDataMap().values()) {
playerData.getStorageData().save();
}
}
public void unload() {
this.playerDataList.clear();
this.worldClaims.clear();
this.claimUniqueIdMap.clear();
this.chunksToClaimsMap.clear();
if (this.theWildernessClaim != null) {
this.theWildernessClaim.unload();
this.theWildernessClaim = null;
}
this.worldUniqueId = null;
}
@Override
public Claim getClaimAt(Vector3i pos) {
final World world = Sponge.getServer().getWorld(this.worldUniqueId).orElse(null);
return this.getClaimAt(VecHelper.toLocation(world, pos), null, null, false);
}
public Claim getClaimAt(Location<World> location, boolean useBorderBlockRadius) {
return this.getClaimAt(location, null, null, useBorderBlockRadius);
}
public Claim getClaimAtPlayer(Location<World> location, GDPlayerData playerData) {
return this.getClaimAt(location, (GDClaim) playerData.lastClaim.get(), playerData, false);
}
public Claim getClaimAtPlayer(Location<World> location, GDPlayerData playerData, boolean useBorderBlockRadius) {
return this.getClaimAt(location, (GDClaim) playerData.lastClaim.get(), playerData, useBorderBlockRadius);
}
public Claim getClaimAt(Location<World> location) {
return this.getClaimAt(location, false);
}
public Claim getClaimAt(Location<World> location, GDClaim cachedClaim, GDPlayerData playerData, boolean useBorderBlockRadius) {
//GPTimings.CLAIM_GETCLAIM.startTimingIfSync();
// check cachedClaim guess first. if the location is inside it, we're done
if (cachedClaim != null && !cachedClaim.isWilderness() && cachedClaim.contains(location, true)) {
// GPTimings.CLAIM_GETCLAIM.stopTimingIfSync();
return cachedClaim;
}
Set<Claim> claimsInChunk = this.getInternalChunksToClaimsMap().get(BlockUtil.getInstance().asLong(location.getBlockX() >> 4, location.getBlockZ() >> 4));
if (useBorderBlockRadius && (playerData != null && !playerData.bypassBorderCheck)) {
final int borderBlockRadius = GriefDefenderPlugin.getActiveConfig(location.getExtent().getUniqueId()).getConfig().claim.borderBlockRadius;
// if borderBlockRadius > 0, check surrounding chunks
if (borderBlockRadius > 0) {
for (Direction direction : BlockUtil.ORDINAL_SET) {
Location<World> currentLocation = location;
for (int i = 0; i < borderBlockRadius; i++) { // Handle depth
currentLocation = currentLocation.getBlockRelative(direction);
Set<Claim> relativeClaims = this.getInternalChunksToClaimsMap().get(BlockUtil.getInstance().asLong(currentLocation.getBlockX() >> 4, currentLocation.getBlockZ() >> 4));
if (relativeClaims != null) {
if (claimsInChunk == null) {
claimsInChunk = new HashSet<>();
}
claimsInChunk.addAll(relativeClaims);
}
}
}
}
}
if (claimsInChunk == null) {
//GPTimings.CLAIM_GETCLAIM.stopTimingIfSync();
return this.getWildernessClaim();
}
for (Claim claim : claimsInChunk) {
GDClaim foundClaim = findClaim((GDClaim) claim, location, playerData, useBorderBlockRadius);
if (foundClaim != null) {
return foundClaim;
}
}
//GPTimings.CLAIM_GETCLAIM.stopTimingIfSync();
// if no claim found, return the world claim
return this.getWildernessClaim();
}
private GDClaim findClaim(GDClaim claim, Location<World> location, GDPlayerData playerData, boolean useBorderBlockRadius) {
if (claim.contains(location, playerData, useBorderBlockRadius)) {
// when we find a top level claim, if the location is in one of its children,
// return the child claim, not the top level claim
for (Claim childClaim : claim.children) {
GDClaim child = (GDClaim) childClaim;
if (!child.children.isEmpty()) {
GDClaim innerChild = findClaim(child, location, playerData, useBorderBlockRadius);
if (innerChild != null) {
return innerChild;
}
}
// check if child has children (Town -> Basic -> Subdivision)
if (child.contains(location, playerData, useBorderBlockRadius)) {
return child;
}
}
return claim;
}
return null;
}
@Override
public List<Claim> getClaimsByName(String name) {
List<Claim> claimList = new ArrayList<>();
for (Claim worldClaim : this.getWorldClaims()) {
Component claimName = worldClaim.getName().orElse(null);
if (claimName != null && claimName != TextComponent.empty()) {
if (PlainComponentSerializer.INSTANCE.serialize(claimName).equalsIgnoreCase(name)) {
claimList.add(worldClaim);
}
}
// check children
for (Claim child : ((GDClaim) worldClaim).getChildren(true)) {
if (child.getUniqueId().toString().equals(name)) {
claimList.add(child);
}
}
}
return claimList;
}
public void resetPlayerData() {
// check migration reset
if (GriefDefenderPlugin.getGlobalConfig().getConfig().playerdata.resetMigrations) {
for (GDPlayerData playerData : this.getPlayerDataMap().values()) {
final PlayerStorageData playerStorage = playerData.getStorageData();
playerStorage.getConfig().setMigratedBlocks(false);
playerStorage.save();
}
}
// migrate playerdata to new claim block system
final int migration3dRate = GriefDefenderPlugin.getGlobalConfig().getConfig().playerdata.migrateVolumeRate;
final int migration2dRate = GriefDefenderPlugin.getGlobalConfig().getConfig().playerdata.migrateAreaRate;
final boolean resetClaimBlockData = GriefDefenderPlugin.getGlobalConfig().getConfig().playerdata.resetAccruedClaimBlocks;
if (migration3dRate <= -1 && migration2dRate <= -1 && !resetClaimBlockData) {
return;
}
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME && migration2dRate >= 0) {
return;
}
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.AREA && migration3dRate >= 0) {
return;
}
for (GDPlayerData playerData : this.getPlayerDataMap().values()) {
final PlayerStorageData playerStorage = playerData.getStorageData();
final int accruedBlocks = playerStorage.getConfig().getAccruedClaimBlocks();
int newAccruedBlocks = accruedBlocks;
// first check reset
if (resetClaimBlockData) {
newAccruedBlocks = playerData.getTotalClaimsCost();
playerStorage.getConfig().setBonusClaimBlocks(0);
} else if (migration3dRate > -1 && !playerStorage.getConfig().hasMigratedBlocks()) {
newAccruedBlocks = accruedBlocks * migration3dRate;
playerStorage.getConfig().setMigratedBlocks(true);
} else if (migration2dRate > -1 && !playerStorage.getConfig().hasMigratedBlocks()) {
newAccruedBlocks = accruedBlocks / migration2dRate;
playerStorage.getConfig().setMigratedBlocks(true);
}
if (newAccruedBlocks < 0) {
newAccruedBlocks = 0;
}
final int maxAccruedBlocks = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), playerData.getSubject(), Options.MAX_ACCRUED_BLOCKS);
if (newAccruedBlocks > maxAccruedBlocks) {
newAccruedBlocks = maxAccruedBlocks;
}
playerStorage.getConfig().setAccruedClaimBlocks(newAccruedBlocks);
playerStorage.save();
}
}
@Override
public UUID getWorldId() {
return this.worldUniqueId;
}
}

View File

@ -0,0 +1,89 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.google.common.collect.ImmutableList;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import net.kyori.text.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class GDClaimResult implements ClaimResult {
private final Component eventMessage;
private final List<Claim> claims;
private final ClaimResultType resultType;
public GDClaimResult(ClaimResultType type) {
this(type, null);
}
public GDClaimResult(ClaimResultType type, Component message) {
this.claims = ImmutableList.of();
this.resultType = type;
this.eventMessage = message;
}
public GDClaimResult(Claim claim, ClaimResultType type) {
this(claim, type, null);
}
public GDClaimResult(Claim claim, ClaimResultType type, Component message) {
List<Claim> claimList = new ArrayList<>();
claimList.add(claim);
this.claims = ImmutableList.copyOf(claimList);
this.resultType = type;
this.eventMessage = message;
}
public GDClaimResult(List<Claim> claims, ClaimResultType type) {
this(claims, type, null);
}
public GDClaimResult(List<Claim> claims, ClaimResultType type, Component message) {
this.claims = ImmutableList.copyOf(claims);
this.resultType = type;
this.eventMessage = message;
}
@Override
public ClaimResultType getResultType() {
return this.resultType;
}
@Override
public Optional<Component> getMessage() {
return Optional.ofNullable(this.eventMessage);
}
@Override
public List<Claim> getClaims() {
return this.claims;
}
}

View File

@ -0,0 +1,187 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.flowpowered.math.vector.Vector3i;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimSchematic;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.storage.FileStorage;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.persistence.DataFormats;
import org.spongepowered.api.data.persistence.DataTranslators;
import org.spongepowered.api.world.BlockChangeFlags;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.extent.ArchetypeVolume;
import org.spongepowered.api.world.schematic.Schematic;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.zip.GZIPOutputStream;
public class GDClaimSchematic implements ClaimSchematic {
private Claim claim;
private Schematic schematic;
private String name;
private Vector3i origin;
private final Instant dateCreated;
// Used during server startup to load schematic
public GDClaimSchematic(Claim claim, Schematic schematic, String name) {
this.claim = claim;
this.schematic = schematic;
this.name = name;
this.origin = claim.getLesserBoundaryCorner();
this.dateCreated = Instant.now();
}
private GDClaimSchematic(Claim claim, Schematic schematic, String name, Vector3i origin) {
this.claim = claim;
this.schematic = schematic;
this.name = name;
this.origin = origin;
this.dateCreated = Instant.now();
}
@Override
public Claim getClaim() {
return this.claim;
}
@Override
public String getName() {
return this.name;
}
@Override
public Instant getDateCreated() {
return this.dateCreated;
}
@Override
public Vector3i getOrigin() {
return this.origin;
}
@Override
public void setOrigin(Vector3i pos) {
this.origin = pos;
}
public Schematic getSchematic() {
return this.schematic;
}
/**
* Applies schematic to claim.
*
* @return If schematic apply was successful, false if not
*/
public boolean apply() {
if (!this.schematic.containsBlock(this.claim.getLesserBoundaryCorner()) && !schematic.containsBlock(this.claim.getGreaterBoundaryCorner())) {
return false;
}
this.schematic.apply(VecHelper.toLocation(((GDClaim)(this.claim)).getWorld(), this.claim.getLesserBoundaryCorner()), BlockChangeFlags.ALL);
return true;
}
public static class ClaimSchematicBuilder implements Builder {
private Claim claim;
private Schematic schematic;
private String name;
private Vector3i origin;
@Override
public Builder claim(Claim claim) {
final World world = ((GDClaim) claim).getWorld();
final ArchetypeVolume volume = world.createArchetypeVolume(this.claim.getLesserBoundaryCorner(), this.claim.getGreaterBoundaryCorner(), new Vector3i(0, 0, 0));
final Schematic schematic = Schematic.builder()
.metaValue(Schematic.METADATA_NAME, name)
.metaValue(Schematic.METADATA_DATE, Instant.now().toString())
.metaValue("UUID", this.claim.getUniqueId().toString())
.volume(volume)
.build();
this.claim = claim;
this.schematic = schematic;
return this;
}
@Override
public Builder name(String name) {
this.name = name;
return this;
}
@Override
public Builder origin(Vector3i origin) {
this.origin = origin;
return this;
}
@Override
public Builder reset() {
this.name = null;
this.origin = null;
this.schematic = null;
return this;
}
@Override
public Optional<ClaimSchematic> build() {
if (this.origin == null) {
//this.origin = new Vector3i(0, 0, 0);
this.origin = this.claim.getLesserBoundaryCorner();
}
final World world = ((GDClaim) this.claim).getWorld();
DataContainer schematicData = DataTranslators.SCHEMATIC.translate(schematic);
final Path schematicPath = GriefDefenderPlugin.getInstance().getWorldEditProvider().getSchematicWorldMap().get(world.getUniqueId()).resolve(this.claim.getUniqueId().toString());
try {
Files.createDirectories(schematicPath);
} catch (IOException e1) {
e1.printStackTrace();
}
File outputFile = schematicPath.resolve(name + ".schematic").toFile();
try {
DataFormats.NBT.writeTo(new GZIPOutputStream(new FileOutputStream(outputFile)), schematicData);
} catch (Exception e) {
e.printStackTrace();
return Optional.empty();
}
final GDClaimSchematic schematic = new GDClaimSchematic(this.claim, this.schematic, this.name, this.origin);
((GDClaim) this.claim).schematics.put(this.name, schematic);
return Optional.of(schematic);
}
}
}

View File

@ -0,0 +1,119 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.permission.Context;
import com.griefdefender.util.SpongeContexts;
public class GDClaimType implements ClaimType {
private final String id;
private final String name;
private final Context defaultContext;
private final Context overrideContext;
private final org.spongepowered.api.service.context.Context spongeDefaultContext;
private final org.spongepowered.api.service.context.Context spongeOverrideContext;
public GDClaimType(String id, String name) {
this.id = id;
this.name = name;
if (name.equalsIgnoreCase("any") || name.equalsIgnoreCase("global")) {
this.defaultContext = ClaimContexts.GLOBAL_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.GLOBAL_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.GLOBAL_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.GLOBAL_OVERRIDE_CONTEXT;
} else if (name.equalsIgnoreCase("admin")) {
this.defaultContext = ClaimContexts.ADMIN_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.ADMIN_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.GLOBAL_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.GLOBAL_OVERRIDE_CONTEXT;
} else if (name.equalsIgnoreCase("basic")) {
this.defaultContext = ClaimContexts.BASIC_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.BASIC_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.GLOBAL_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.GLOBAL_OVERRIDE_CONTEXT;
} else if (name.equalsIgnoreCase("subdivision")) {
this.defaultContext = ClaimContexts.SUBDIVISION_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.SUBDIVISION_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.SUBDIVISION_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.SUBDIVISION_OVERRIDE_CONTEXT;
} else if (name.equalsIgnoreCase("town")) {
this.defaultContext = ClaimContexts.TOWN_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.TOWN_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.TOWN_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.TOWN_OVERRIDE_CONTEXT;
} else if (name.equalsIgnoreCase("wilderness")) {
this.defaultContext = ClaimContexts.WILDERNESS_DEFAULT_CONTEXT;
this.overrideContext = ClaimContexts.WILDERNESS_OVERRIDE_CONTEXT;
this.spongeDefaultContext = SpongeContexts.WILDERNESS_DEFAULT_CONTEXT;
this.spongeOverrideContext = SpongeContexts.WILDERNESS_OVERRIDE_CONTEXT;
} else {
this.defaultContext = new Context("gd_claim_default", name.toLowerCase());
this.overrideContext = new Context("gd_claim_override", name.toLowerCase());
this.spongeDefaultContext = new org.spongepowered.api.service.context.Context("gd_claim_default", name.toLowerCase());
this.spongeOverrideContext = new org.spongepowered.api.service.context.Context("gd_claim_override", name.toLowerCase());
}
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
public String toString() {
return this.id;
}
@Override
public Context getContext() {
return this.defaultContext;
}
@Override
public Context getDefaultContext() {
return this.defaultContext;
}
@Override
public Context getOverrideContext() {
return this.overrideContext;
}
public org.spongepowered.api.service.context.Context getSpongeDefaultContext() {
return this.spongeDefaultContext;
}
public org.spongepowered.api.service.context.Context getSpongeOverrideContext() {
return this.spongeOverrideContext;
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.griefdefender.api.claim.ShovelType;
public class GDShovelType implements ShovelType {
private final String id;
private final String name;
public GDShovelType(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
}

View File

@ -0,0 +1,21 @@
package com.griefdefender.claim;
import com.flowpowered.math.vector.Vector3i;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.Town;
import com.griefdefender.api.data.TownData;
import org.spongepowered.api.world.World;
import java.util.UUID;
public class GDTown extends GDClaim implements Town {
public GDTown(World world, Vector3i point1, Vector3i point2, ClaimType type, UUID ownerUniqueId, boolean cuboid) {
super(world, point1, point2, type, ownerUniqueId, cuboid);
}
@Override
public TownData getData() {
return (TownData) this.claimData;
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.claim;
import com.griefdefender.api.claim.TrustType;
public class GDTrustType implements TrustType {
private final String id;
private final String name;
public GDTrustType(String id, String name) {
this.id = id.toLowerCase();
this.name = name.toLowerCase();
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
@Override
public String toString() {
return this.id;
}
}

View File

@ -0,0 +1,973 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.configuration.category.CustomFlagGroupCategory;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDFlagPermissionEvent;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.CustomFlagData;
import com.griefdefender.permission.flag.GDActiveFlagData;
import com.griefdefender.permission.flag.GDCustomFlagDefinition;
import com.griefdefender.permission.ui.ClaimClickData;
import com.griefdefender.permission.ui.FlagData;
import com.griefdefender.permission.ui.MenuType;
import com.griefdefender.permission.ui.UIHelper;
import com.griefdefender.permission.ui.FlagData.FlagContextHolder;
import com.griefdefender.registry.FlagRegistryModule;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.PaginationUtil;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.item.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public abstract class ClaimFlagBase extends BaseCommand {
private static final Component whiteOpenBracket = TextComponent.of("[", TextColor.AQUA);
private static final Component whiteCloseBracket = TextComponent.of("]", TextColor.AQUA);
protected GDPermissionHolder subject;
protected ClaimSubjectType subjectType;
protected String friendlySubjectName;
private final Cache<UUID, String> lastActivePresetMenuMap = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
private final Cache<UUID, String> lastActiveMenuTypeMap = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
protected ClaimFlagBase(ClaimSubjectType type) {
this.subjectType = type;
}
public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject;
String commandFlag = null;
String target = null;
String value = null;
String contexts = null;
final String arguments = String.join(" ", args);
int index = arguments.indexOf("context[");
if (index != -1) {
contexts = arguments.substring(index, arguments.length());
}
if (args.length > 0) {
if (args.length < 3) {
throw new InvalidCommandArgument();
}
commandFlag = args[0];
target = args[1];
value = args[2];
}
final Flag flag = FlagRegistryModule.getInstance().getById(commandFlag).orElse(null);
if (commandFlag != null && flag == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_NOT_FOUND, ImmutableMap.of(
"flag", commandFlag)));
return;
}
if (flag != null && !player.hasPermission(GDPermissions.USER_CLAIM_FLAGS + "." + flag.getName().toLowerCase())) {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_USE);
return;
}
if (target != null && target.equalsIgnoreCase("hand")) {
ItemStack stack = NMSUtil.getInstance().getActiveItem(player);
if (stack != null) {
target = GDPermissionManager.getInstance().getPermissionIdentifier(stack);
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
if (contextSet == null) {
return;
}
if (claim != null) {
if (flag == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_FLAGS)) {
String defaultGroup = "";
for (Entry<String, CustomFlagGroupCategory> groupEntry : GriefDefenderPlugin.getGlobalConfig().getConfig().customFlags.getGroups().entrySet()) {
final String permission = groupEntry.getValue().isAdminGroup() ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE;
if (!player.hasPermission(permission + "." + groupEntry.getKey()) && !src.getInternalPlayerData().canIgnoreClaim(claim)) {
continue;
}
defaultGroup = groupEntry.getKey();
break;
}
if (!defaultGroup.isEmpty()) {
showCustomFlags(src, claim, defaultGroup);
} else {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_USE);
}
return;
} else if (flag != null && value != null) {
GDCauseStackManager.getInstance().pushCause(player);
PermissionResult result = CommandHelper.addFlagPermission(player, this.subject, claim, flag, target, PermissionUtil.getInstance().getTristateFromString(value.toUpperCase()), contextSet);
final String flagTarget = target;
if (result.getResultType() == ResultTypes.TARGET_NOT_VALID) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_INVALID_TARGET,
ImmutableMap.of("target", flagTarget,
"flag", flag)));
} else if (result.getResultType() == ResultTypes.NO_PERMISSION) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_FLAG_USE);
}
GDCauseStackManager.getInstance().popCause();
return;
}
} else {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_FOUND);
}
}
protected void showCustomFlags(GDPermissionUser src, GDClaim claim, String displayGroup) {
final Player player = src.getOnlinePlayer();
final String lastPermissionMenuType = this.lastActivePresetMenuMap.getIfPresent(player.getUniqueId());
if (lastPermissionMenuType != null && !lastPermissionMenuType.equalsIgnoreCase(displayGroup.toLowerCase())) {
PaginationUtil.getInstance().resetActivePage(player.getUniqueId());
}
TextComponent.Builder flagHeadBuilder = TextComponent.builder()
.append(" Displaying :", TextColor.AQUA);
final Map<String, CustomFlagGroupCategory> flagGroups = GriefDefenderPlugin.getGlobalConfig().getConfig().customFlags.getGroups();
List<String> groups = new ArrayList<>();
for (Map.Entry<String, CustomFlagGroupCategory> flagGroupEntry : flagGroups.entrySet()) {
final CustomFlagGroupCategory flagGroupCat = flagGroupEntry.getValue();
if (!flagGroupCat.isEnabled()) {
continue;
}
final String groupName = flagGroupEntry.getKey();
final boolean isAdminGroup = GriefDefenderPlugin.getGlobalConfig().getConfig().customFlags.getGroups().get(groupName).isAdminGroup();
final String permission = isAdminGroup ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE;
if (!player.hasPermission(permission + "." + groupName) && !src.getInternalPlayerData().canIgnoreClaim(claim)) {
continue;
}
groups.add(groupName);
}
final CustomFlagGroupCategory flagGroupCat = flagGroups.get(displayGroup);
if (flagGroupCat == null || flagGroupCat.getFlagDefinitions().isEmpty()) {
TextAdapter.sendComponent(player, TextComponent.of("No custom flag definitions were found for group '" + displayGroup + "'."));
return;
}
Collections.sort(groups);
for (String group : groups) {
flagHeadBuilder.append(" ").append(displayGroup.equalsIgnoreCase(group) ? TextComponent.builder()
.append(whiteOpenBracket)
.append(group.toUpperCase(), flagGroups.get(group).isAdminGroup() ? TextColor.RED : TextColor.GOLD)
.append(whiteCloseBracket).build() :
TextComponent.builder().append(group.toUpperCase(), TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createCustomFlagConsumer(src, claim, group))))
.build());
}
List<Component> textComponents = new ArrayList<>();
for (GDCustomFlagDefinition customFlag : flagGroupCat.getFlagDefinitions().values()) {
Component flagText = TextComponent.builder()
.append(getCustomFlagText(customFlag))
.append(" ")
.append(this.getCustomClickableText(src, claim, customFlag, displayGroup))
.build();
textComponents.add(flagText);
}
Collections.sort(textComponents, UIHelper.PLAIN_COMPARATOR);
int fillSize = 20 - (textComponents.size() + 2);
for (int i = 0; i < fillSize; i++) {
textComponents.add(TextComponent.of(" "));
}
String lastMenu = this.lastActiveMenuTypeMap.getIfPresent(src.getUniqueId());
MenuType lastActiveMenu = MenuType.CLAIM;
if (lastMenu != null) {
lastActiveMenu = MenuType.valueOf(lastMenu.toUpperCase());
}
Component footer = null;
if (player.hasPermission(GDPermissions.ADVANCED_FLAGS)) {
footer = TextComponent.builder().append(whiteOpenBracket)
.append(TextComponent.of("PRESET").color(TextColor.GOLD)).append(whiteCloseBracket)
.append(" ")
.append(TextComponent.builder()
.append(TextComponent.of("ADVANCED").color(TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimFlagConsumer(src, claim, lastActiveMenu)))))
.build())
.build();
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(flagHeadBuilder.build()).padding(TextComponent.builder(" ").decoration(TextDecoration.STRIKETHROUGH, true).build()).contents(textComponents).footer(footer);
final PaginationList paginationList = paginationBuilder.build();
Integer activePage = 1;
activePage = PaginationUtil.getInstance().getActivePage(player.getUniqueId());
if (activePage == null) {
activePage = 1;
}
this.lastActivePresetMenuMap.put(player.getUniqueId(), displayGroup.toLowerCase());
paginationList.sendTo(player, activePage);
}
protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType displayType) {
final Player player = src.getOnlinePlayer();
boolean isAdmin = false;
if (player.hasPermission(GDPermissions.DELETE_CLAIM_ADMIN)) {
isAdmin = true;
}
final String lastPermissionMenuType = this.lastActiveMenuTypeMap.getIfPresent(player.getUniqueId());
if (lastPermissionMenuType != null && !lastPermissionMenuType.equalsIgnoreCase(displayType.name())) {
PaginationUtil.getInstance().resetActivePage(player.getUniqueId());
}
final Component showOverrideText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("OVERRIDE", TextColor.RED)));
final Component showDefaultText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("DEFAULT", TextColor.LIGHT_PURPLE)));
final Component showClaimText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("CLAIM", TextColor.GOLD)));
final Component showInheritText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("INHERIT", TextColor.AQUA)));
Component defaultFlagText = TextComponent.empty();
if (isAdmin) {
defaultFlagText = TextComponent.builder("")
.append(displayType == MenuType.DEFAULT ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("DEFAULT", TextColor.LIGHT_PURPLE)
.append(whiteCloseBracket).build() : TextComponent.of("DEFAULT", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimFlagConsumer(src, claim, MenuType.DEFAULT))))
.hoverEvent(HoverEvent.showText(showDefaultText)).build();
}
final Component overrideFlagText = TextComponent.builder("")
.append(displayType == MenuType.OVERRIDE ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("OVERRIDE", TextColor.RED)
.append(whiteCloseBracket).build() : TextComponent.of("OVERRIDE", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimFlagConsumer(src, claim, MenuType.OVERRIDE))))
.hoverEvent(HoverEvent.showText(showOverrideText)).build();
final Component claimFlagText = TextComponent.builder("")
.append(displayType == MenuType.CLAIM ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("CLAIM", TextColor.YELLOW)
.append(whiteCloseBracket).build() : TextComponent.of("CLAIM", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimFlagConsumer(src, claim, MenuType.CLAIM))))
.hoverEvent(HoverEvent.showText(showClaimText)).build();
final Component inheritFlagText = TextComponent.builder("")
.append(displayType == MenuType.INHERIT ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("INHERIT", TextColor.AQUA)
.append(whiteCloseBracket).build() : TextComponent.of("INHERIT", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimFlagConsumer(src, claim, MenuType.INHERIT))))
.hoverEvent(HoverEvent.showText(showInheritText)).build();
Component claimFlagHead = TextComponent.empty();
if (this.subjectType == ClaimSubjectType.GLOBAL) {
if (isAdmin) {
claimFlagHead = TextComponent.builder("")
.append(" Displaying : ", TextColor.AQUA)
.append(defaultFlagText)
.append(" ")
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
} else {
claimFlagHead = TextComponent.builder("")
.append(" Displaying : ", TextColor.AQUA)
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
}
} else {
claimFlagHead = TextComponent.builder("")
.append(" " + this.subjectType.getFriendlyName() + " ", TextColor.AQUA)
.append(this.friendlySubjectName, TextColor.YELLOW)
.append(" : ", TextColor.AQUA)
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
}
Set<Context> defaultContexts = new HashSet<>();
Set<Context> overrideContexts = new HashSet<>();
if (claim.isAdminClaim()) {
defaultContexts.add(ClaimContexts.ADMIN_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.ADMIN_OVERRIDE_CONTEXT);
} else if (claim.isBasicClaim() || claim.isSubdivision()) {
defaultContexts.add(ClaimContexts.BASIC_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.BASIC_OVERRIDE_CONTEXT);
} else if (claim.isTown()) {
defaultContexts.add(ClaimContexts.TOWN_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.TOWN_OVERRIDE_CONTEXT);
} else {
defaultContexts.add(ClaimContexts.WILDERNESS_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.WILDERNESS_OVERRIDE_CONTEXT);
}
defaultContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, FlagData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getTransientPermissions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
} else if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
}
}
final List<Claim> inheritParents = claim.getInheritedParents();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getPermanentPermissions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
} else if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
}
if (displayType != MenuType.DEFAULT) {
if (contextSet.contains(claim.getContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.CLAIM, mapEntry.getValue());
}
for (Claim parentClaim : inheritParents) {
GDClaim parent = (GDClaim) parentClaim;
// check parent context
if (contextSet.contains(parent.getContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.INHERIT, mapEntry.getValue());
}
}
if (contextSet.contains(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT)) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
}
if (contextSet.contains(claim.getOverrideClaimContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
} else if (contextSet.contains(claim.getOverrideTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
}
}
}
final Map<String, Map<Integer, Component>> textMap = new TreeMap<>();
for (Entry<String, FlagData> mapEntry : filteredContextMap.entrySet()) {
final FlagData flagData = mapEntry.getValue();
final Flag flag = flagData.flag;
for (FlagContextHolder flagHolder : flagData.flagContextMap.values()) {
if (displayType != MenuType.CLAIM && flagHolder.getType() != displayType) {
continue;
}
final Set<Context> contexts = flagHolder.getAllContexts();
Component flagText = TextComponent.builder()
.append(getFlagText(flag, contexts))
.append(" ")
.append(this.getClickableText(src, claim, flag, flagHolder, contexts, displayType))
.build();
final int hashCode = Objects.hash(flag.getPermission(), contexts);
Map<Integer, Component> componentMap = textMap.get(flag.getPermission());
if (componentMap == null) {
componentMap = new HashMap<>();
componentMap.put(hashCode, flagText);
textMap.put(flag.getPermission(), componentMap);
} else {
componentMap.put(hashCode, flagText);
}
}
}
List<Component> textList = new ArrayList<>();
for (Entry<String, Map<Integer, Component>> mapEntry : textMap.entrySet()) {
textList.addAll(mapEntry.getValue().values());
}
Collections.sort(textList, UIHelper.PLAIN_COMPARATOR);
int fillSize = 20 - (textList.size() + 2);
for (int i = 0; i < fillSize; i++) {
textList.add(TextComponent.of(" "));
}
String lastActivePresetMenu = this.lastActivePresetMenuMap.getIfPresent(src.getUniqueId());
if (lastActivePresetMenu == null) {
lastActivePresetMenu = "user";
}
Component footer = null;
if (player.hasPermission(GDPermissions.ADVANCED_FLAGS)) {
footer = TextComponent.builder().append(TextComponent.builder()
.append(TextComponent.of("PRESET").color(TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createCustomFlagConsumer(src, claim, lastActivePresetMenu)))))
.build())
.append(" ")
.append(whiteOpenBracket)
.append(TextComponent.of("ADVANCED").color(TextColor.RED))
.append(whiteCloseBracket)
.build();
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(claimFlagHead).padding(TextComponent.builder(" ").decoration(TextDecoration.STRIKETHROUGH, true).build()).contents(textList).footer(footer);
final PaginationList paginationList = paginationBuilder.build();
Integer activePage = 1;
activePage = PaginationUtil.getInstance().getActivePage(player.getUniqueId());
if (activePage == null) {
activePage = 1;
}
this.lastActiveMenuTypeMap.put(player.getUniqueId(), displayType.name().toLowerCase());
paginationList.sendTo(player, activePage);
}
private void addFilteredContexts(Map<String, FlagData> filteredContextMap, Set<Context> contexts, MenuType type, Map<String, Boolean> permissions) {
for (Map.Entry<String, Boolean> permissionEntry : permissions.entrySet()) {
final Flag flag = FlagRegistryModule.getInstance().getById(permissionEntry.getKey()).orElse(null);
if (flag == null) {
continue;
}
final FlagData flagData = filteredContextMap.get(permissionEntry.getKey());
if (flagData != null) {
flagData.addContexts(flag, permissionEntry.getValue(), type, contexts);
} else {
filteredContextMap.put(permissionEntry.getKey(), new FlagData(flag, permissionEntry.getValue(), type, contexts));
}
}
}
private Component getCustomFlagText(GDCustomFlagDefinition customFlag) {
TextComponent definitionType = TextComponent.empty();
TextColor flagColor = TextColor.GREEN;
for (Context context : customFlag.getDefinitionContexts()) {
if (context.getKey().contains("default")) {
definitionType = TextComponent.builder()
.append("\n")
.append(MessageCache.getInstance().LABEL_TYPE.color(TextColor.AQUA))
.append(" : ", TextColor.WHITE)
.append("DEFAULT", TextColor.LIGHT_PURPLE)
.append(" ")
.append(context.getValue().toUpperCase(), TextColor.GRAY)
.build();
flagColor = TextColor.LIGHT_PURPLE;
} else if (context.getKey().contains("override")) {
definitionType = TextComponent.builder()
.append("\n")
.append(MessageCache.getInstance().LABEL_TYPE.color(TextColor.AQUA))
.append(" : ", TextColor.WHITE)
.append("OVERRIDE", TextColor.RED)
.append(" ")
.append(context.getValue().toUpperCase(), TextColor.GRAY)
.build();
flagColor = TextColor.RED;
}
}
if (definitionType == TextComponent.empty()) {
definitionType = TextComponent.builder()
.append("\n")
.append(MessageCache.getInstance().LABEL_TYPE.color(TextColor.AQUA))
.append(" : ", TextColor.WHITE)
.append("CLAIM", TextColor.YELLOW)
.build();
}
final Component baseFlagText = TextComponent.builder()
.append(customFlag.getDisplayName(), flagColor)
.append(" ")
.hoverEvent(HoverEvent.showText(TextComponent.builder()
.append(customFlag.getDescription())
.append(definitionType)
.build())).build();
return baseFlagText;
}
private TextColor getCustomFlagColor(GDCustomFlagDefinition customFlag) {
TextColor flagColor = TextColor.GREEN;
for (Context context : customFlag.getDefinitionContexts()) {
if (context.getKey().contains("default")) {
flagColor = TextColor.LIGHT_PURPLE;
break;
} else if (context.getKey().contains("override")) {
flagColor = TextColor.RED;
break;
}
}
return flagColor;
}
private Component getFlagText(Flag flag, Set<Context> contexts) {
boolean customContext = UIHelper.containsCustomContext(contexts);
final Component baseFlagText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(flag.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder()
.append(flag.getDescription())
.build())).build();
return baseFlagText;
}
private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GDCustomFlagDefinition customFlag, String flagGroup) {
boolean hasHover = false;
TextComponent.Builder hoverBuilder = TextComponent.builder();
final Player player = src.getOnlinePlayer();
boolean hasEditPermission = true;
Component denyReason = claim.allowEdit(player);
if (denyReason != null) {
hoverBuilder.append(denyReason).append("\n");
hasEditPermission = false;
hasHover = true;
}
final boolean isAdminGroup = GriefDefenderPlugin.getGlobalConfig().getConfig().customFlags.getGroups().get(flagGroup).isAdminGroup();
final String permission = isAdminGroup ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE;
// check flag perm
if (!player.hasPermission(permission + "." + flagGroup + "." + customFlag.getDisplayName())) {
hoverBuilder.append(MessageCache.getInstance().PERMISSION_FLAG_USE).append("\n");
hasEditPermission = false;
hasHover = true;
}
List<GDActiveFlagData> dataResults = new ArrayList<>();
boolean hasGDContext = false;
Set<Context> definitionContexts = new HashSet<>(customFlag.getDefinitionContexts());
for (Context context : customFlag.getDefinitionContexts()) {
if (context.getKey().contains("gd_claim")) {
hasGDContext = true;
break;
}
}
if (!hasGDContext) {
definitionContexts.add(claim.getContext());
}
for (CustomFlagData flagData : customFlag.getFlagData()) {
final Set<Context> filteredContexts = new HashSet<>();
for (Context context : definitionContexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredContexts.add(context);
}
// Check override
filteredContexts.addAll(flagData.getContexts());
Set<Context> newContexts = new HashSet<>(filteredContexts);
newContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
newContexts.add(claim.getOverrideTypeContext());
newContexts.add(claim.getOverrideClaimContext());
Tristate result = PermissionUtil.getInstance().getPermissionValueWithRequiredContexts(claim, GriefDefenderPlugin.DEFAULT_HOLDER, flagData.getFlag().getPermission(), newContexts, "gd_claim");
if (result != Tristate.UNDEFINED) {
dataResults.add(new GDActiveFlagData(flagData, result, GDActiveFlagData.Type.OVERRIDE));
continue;
}
// Check claim
newContexts = new HashSet<>(filteredContexts);
newContexts.add(claim.getContext());
result = PermissionUtil.getInstance().getPermissionValueWithRequiredContexts(claim, GriefDefenderPlugin.DEFAULT_HOLDER, flagData.getFlag().getPermission(), newContexts, "gd_claim");
if (result != Tristate.UNDEFINED) {
dataResults.add(new GDActiveFlagData(flagData, result, GDActiveFlagData.Type.CLAIM));
continue;
}
// Check default
newContexts = new HashSet<>(filteredContexts);
newContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
newContexts.add(claim.getDefaultTypeContext());
result = PermissionUtil.getInstance().getPermissionValueWithRequiredContexts(claim, GriefDefenderPlugin.DEFAULT_HOLDER, flagData.getFlag().getPermission(), newContexts, "gd_claim");
if (result != Tristate.UNDEFINED) {
dataResults.add(new GDActiveFlagData(flagData, result, GDActiveFlagData.Type.DEFAULT));
continue;
}
dataResults.add(new GDActiveFlagData(flagData, result, GDActiveFlagData.Type.UNDEFINED));
}
boolean properResult = true;
Tristate lastResult = null;
for (GDActiveFlagData activeFlagData : dataResults) {
final Tristate result = activeFlagData.getValue();
if (lastResult == null) {
lastResult = result;
} else if (lastResult != result) {
properResult = false;
break;
}
}
TextComponent.Builder valueBuilder = TextComponent.builder();
if (!properResult) {
if (hasEditPermission) {
hoverBuilder.append("Active Data : \n");
for (GDActiveFlagData activeFlagData : dataResults) {
hoverBuilder.append(activeFlagData.getComponent())
.append("\n");
}
hasHover = true;
}
valueBuilder.append("partial");
lastResult = null;
} else {
TextColor valueColor = TextColor.GRAY;
if (lastResult == Tristate.TRUE) {
valueColor = TextColor.GOLD;
} else if (lastResult == Tristate.FALSE) {
valueColor = TextColor.RED;
}
valueBuilder.append(String.valueOf(lastResult).toLowerCase(), valueColor);
}
if (hasEditPermission) {
if (lastResult == null || lastResult == Tristate.UNDEFINED) {
hoverBuilder.append(MessageCache.getInstance().FLAG_UI_CLICK_ALLOW);
} else if (lastResult == Tristate.TRUE) {
hoverBuilder.append(MessageCache.getInstance().FLAG_UI_CLICK_DENY);
} else {
hoverBuilder.append(MessageCache.getInstance().FLAG_UI_CLICK_REMOVE);
}
if (!customFlag.getDefinitionContexts().isEmpty()) {
hoverBuilder.append("\nContexts: ");
}
for (Context context : customFlag.getDefinitionContexts()) {
hoverBuilder.append("\n");
final String key = context.getKey();
final String value = context.getValue();
TextColor keyColor = TextColor.AQUA;
if (key.contains("default")) {
keyColor = TextColor.LIGHT_PURPLE;
} else if (key.contains("override")) {
keyColor = TextColor.RED;
} else if (key.contains("server")) {
keyColor = TextColor.GRAY;
}
hoverBuilder.append(key, keyColor)
.append("=", TextColor.WHITE)
.append(value.replace("minecraft:", ""), TextColor.GRAY);
}
hasHover = true;
}
if (hasHover) {
valueBuilder.hoverEvent(HoverEvent.showText(hoverBuilder.build()));
}
TextComponent.Builder textBuilder = null;
if (hasEditPermission) {
textBuilder = TextComponent.builder()
.append(valueBuilder
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createCustomFlagConsumer(src, claim, customFlag, lastResult, flagGroup))))
.build());
} else {
textBuilder = TextComponent.builder()
.append(valueBuilder
.build());
}
return textBuilder.build();
}
private Component getClickableText(GDPermissionUser src, GDClaim claim, Flag flag, FlagContextHolder flagHolder, Set<Context> contexts, MenuType displayType) {
Component hoverEventText = TextComponent.empty();
final MenuType flagType = flagHolder.getType();
final Player player = src.getOnlinePlayer();
boolean hasEditPermission = true;
if (displayType == MenuType.DEFAULT) {
if (!src.getInternalPlayerData().canManageFlagDefaults) {
hoverEventText = MessageCache.getInstance().PERMISSION_FLAG_DEFAULTS;
hasEditPermission = false;
}
} else if (flagType == MenuType.OVERRIDE) {
if (!src.getInternalPlayerData().canManageFlagOverrides) {
hoverEventText = MessageCache.getInstance().PERMISSION_FLAG_OVERRIDES;
hasEditPermission = false;
}
} else if (flagType == MenuType.INHERIT) {
UUID parentUniqueId = null;
for (Context context : contexts) {
if (context.getKey().equals("gd_claim")) {
try {
parentUniqueId = UUID.fromString(context.getValue());
} catch (IllegalArgumentException e) {
// ignore
}
}
}
// should never happen but just in case
if (parentUniqueId == null) {
hoverEventText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_UI_INHERIT_PARENT,
ImmutableMap.of("name", "unknown"));
hasEditPermission = false;
} else {
final GDClaim parentClaim = (GDClaim) GriefDefenderPlugin.getInstance().dataStore.getClaim(claim.getWorldUniqueId(), parentUniqueId);
hoverEventText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_UI_INHERIT_PARENT,
ImmutableMap.of("name", parentClaim.getFriendlyNameType()));
hasEditPermission = false;
}
} else {
Component denyReason = claim.allowEdit(player);
if (denyReason != null) {
hoverEventText = denyReason;
hasEditPermission = false;
} else {
// check flag perm
if (!player.hasPermission(GDPermissions.USER_CLAIM_FLAGS + "." + flag.getName().toLowerCase())) {
hoverEventText = MessageCache.getInstance().PERMISSION_FLAG_USE;
hasEditPermission = false;
}
}
}
Set<Context> sortedContexts = new TreeSet<>(new Comparator<Context>() {
@Override
public int compare(Context o1, Context o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
sortedContexts.addAll(contexts);
final boolean customContexts = UIHelper.containsCustomContext(contexts);
Component flagContexts = UIHelper.getFriendlyContextString(claim, contexts);
Component hoverText = TextComponent.builder()
.append(hoverEventText)
.append(hoverEventText == TextComponent.empty() ? "" : "\n")
.append(UIHelper.getPermissionMenuTypeHoverText(flagHolder, displayType))
.append("\n")
.append(flagContexts)
.build();
Tristate newValue = Tristate.UNDEFINED;
Boolean value = flagHolder.getValue();
if (customContexts) {
if (value) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.TRUE;
}
} else {
if (displayType == MenuType.DEFAULT || (displayType == MenuType.CLAIM && flagHolder.getType() == MenuType.DEFAULT)) {
newValue = Tristate.fromBoolean(!value);
} else {
// Always fall back to transient default
newValue = Tristate.UNDEFINED;
}
}
TextComponent.Builder valueBuilder = TextComponent.builder()
.append(String.valueOf(value), flagHolder.getColor())
.hoverEvent(HoverEvent.showText(hoverText));
TextComponent.Builder textBuilder = null;
if (hasEditPermission) {
textBuilder = TextComponent.builder()
.append(valueBuilder
.hoverEvent(HoverEvent.showText(hoverText))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, flag, flagHolder, newValue, contexts, displayType))))
.build());
} else {
textBuilder = TextComponent.builder()
.append(valueBuilder
.hoverEvent(HoverEvent.showText(hoverText))
.build());
}
// check source/target
Component source = null;
Component target = null;
final Component whiteOpenBracket = TextComponent.of("[", TextColor.WHITE);
final Component whiteCloseBracket = TextComponent.of("]", TextColor.WHITE);
for (Context context : contexts) {
if (context.getKey().equals(ContextKeys.SOURCE)) {
source = TextComponent.builder()
.append(whiteOpenBracket)
.append("s", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_SOURCE))
.build();
textBuilder.append(" ").append(source);
} else if (context.getKey().equals(ContextKeys.TARGET)) {
target = TextComponent.builder()
.append(whiteOpenBracket)
.append("t", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_TARGET))
.build();
textBuilder.append(" ").append(target);
}
}
if (customContexts) {
textBuilder.append(" ")
.append("[", TextColor.WHITE)
.append(TextComponent.builder()
.append("x", TextColor.RED)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().FLAG_UI_CLICK_REMOVE))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, flag, flagHolder, Tristate.UNDEFINED, contexts, displayType))))
.build())
.append("]", TextColor.WHITE);
}
return textBuilder.build();
}
private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDCustomFlagDefinition customFlag, Tristate currentValue, String displayType) {
final Player player = src.getOnlinePlayer();
return consumer -> {
GDCauseStackManager.getInstance().pushCause(player);
boolean hasGDContext = false;
Set<Context> definitionContexts = new HashSet<>(customFlag.getDefinitionContexts());
for (Context context : customFlag.getDefinitionContexts()) {
if (context.getKey().contains("gd_claim")) {
hasGDContext = true;
break;
}
}
if (!hasGDContext) {
definitionContexts.add(claim.getContext());
}
for (CustomFlagData flagData : customFlag.getFlagData()) {
final Set<Context> newContexts = new HashSet<>(definitionContexts);
newContexts.addAll(flagData.getContexts());
Tristate newValue = Tristate.UNDEFINED;
if (currentValue == null || currentValue == Tristate.UNDEFINED) {
newValue = Tristate.TRUE;
} else if (currentValue == Tristate.TRUE) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.UNDEFINED;
}
PermissionResult result = null;
final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event);
if (event.cancelled()) {
return;
}
result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
}
GDCauseStackManager.getInstance().popCause();
showCustomFlags(src, claim, displayType);
};
}
private Consumer<CommandSource> createFlagConsumer(GDPermissionUser src, GDClaim claim, Flag flag, FlagContextHolder flagHolder, Tristate newValue, Set<Context> contexts, MenuType displayType) {
final Player player = src.getOnlinePlayer();
return consumer -> {
Set<Context> newContexts = new HashSet<>();
GDCauseStackManager.getInstance().pushCause(player);
final boolean isCustom = UIHelper.containsCustomContext(contexts);
if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext());
} else {
newContexts.addAll(contexts);
}
// Remove server context
final Iterator<Context> iterator = newContexts.iterator();
while (iterator.hasNext()) {
final Context context = iterator.next();
if (context.getKey().equals("server")) {
iterator.remove();
}
}
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flag, newValue, newContexts);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
return;
}
PermissionResult result = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts);
if (result.successful()) {
showFlagPermissions(src, claim, displayType);
}
};
}
private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, String flagGroup) {
return consumer -> {
showCustomFlags(src, claim, flagGroup);
};
}
private Consumer<CommandSource> createClaimFlagConsumer(GDPermissionUser src, GDClaim claim, MenuType flagType) {
return consumer -> {
showFlagPermissions(src, claim, flagType);
};
}
}

View File

@ -0,0 +1,913 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.api.permission.option.type.GameModeType;
import com.griefdefender.api.permission.option.type.GameModeTypes;
import com.griefdefender.api.permission.option.type.WeatherType;
import com.griefdefender.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.option.GDOption;
import com.griefdefender.permission.ui.ClaimClickData;
import com.griefdefender.permission.ui.FlagData;
import com.griefdefender.permission.ui.MenuType;
import com.griefdefender.permission.ui.OptionData;
import com.griefdefender.permission.ui.OptionData.OptionContextHolder;
import com.griefdefender.permission.ui.UIHelper;
import com.griefdefender.permission.ui.FlagData.FlagContextHolder;
import com.griefdefender.registry.FlagRegistryModule;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.PaginationUtil;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ClaimOptionBase extends BaseCommand {
protected GDPermissionHolder subject;
protected ClaimSubjectType subjectType;
protected String friendlySubjectName;
private final Cache<UUID, MenuType> lastActiveMenuTypeMap = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
protected ClaimOptionBase(ClaimSubjectType type) {
this.subjectType = type;
}
public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject;
String commandOption = null;
String value = null;
String contexts = null;
final String arguments = String.join(" ", args);
int index = arguments.indexOf("context[");
if (index != -1) {
contexts = arguments.substring(index, arguments.length());
}
if (args.length > 0) {
if (args.length < 2) {
throw new InvalidCommandArgument();
}
commandOption = args[0];
value = args[1];
}
Option option = null;
if (commandOption != null) {
option = GriefDefender.getRegistry().getType(Option.class, commandOption).orElse(null);
if (commandOption != null && option == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_FOUND, ImmutableMap.of(
"option", commandOption)));
return;
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (claim.isWilderness()) {
if(!playerData.canManageWilderness && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GLOBAL_OPTION);
return;
}
} else if (!claim.isTown() && !playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GLOBAL_OPTION);
return;
}
if (option != null) {
if (option.isGlobal()) {
if (!player.hasPermission(GDPermissions.MANAGE_GLOBAL_OPTIONS +"." + option.getPermission().toLowerCase())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GLOBAL_OPTION);
return;
}
} else if (!player.hasPermission(GDPermissions.USER_CLAIM_OPTIONS +"." + option.getPermission().toLowerCase())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_PLAYER_OPTION);
return;
}
}
if (!playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) {
final Component denyMessage = claim.allowEdit(player);
if (denyMessage != null) {
GriefDefenderPlugin.sendMessage(player, denyMessage);
return;
}
}
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
if (contextSet == null) {
return;
}
if (claim != null) {
if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) {
showOptionPermissions(src, (GDClaim) claim, MenuType.CLAIM);
return;
} else if (option != null && value != null) {
if (!((GDOption) option).validateStringValue(value, false)) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_INVALID_VALUE,
ImmutableMap.of(
"value", value,
"option", option.getName(),
"type", option.getAllowedType().getSimpleName())));
return;
}
MenuType type = MenuType.DEFAULT;
for (Context context : contextSet) {
if (context.getKey().equals(ContextKeys.CLAIM)) {
type = MenuType.CLAIM;
break;
}
if (context.getKey().equals(ContextKeys.CLAIM_OVERRIDE)) {
type = MenuType.OVERRIDE;
break;
}
}
if (!option.isGlobal()) {
contextSet.add(claim.getContext());
if (contextSet.isEmpty() ) {
type = MenuType.CLAIM;
}
}
GDCauseStackManager.getInstance().pushCause(player);
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), value, contextSet);
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_SET_TARGET,
ImmutableMap.of(
"type", type.name().toUpperCase(),
"option", option.getName(),
"contexts", UIHelper.getFriendlyContextString(claim, contextSet),
"value", TextComponent.of(value).color(TextColor.LIGHT_PURPLE),
"target", subject.getFriendlyName())));
GDCauseStackManager.getInstance().popCause();
return;
}
}
}
protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuType displayType) {
boolean isAdmin = false;
final Player player = src.getOnlinePlayer();
final GDPlayerData playerData = src.getInternalPlayerData();
final boolean isTaxEnabled = GriefDefenderPlugin.getActiveConfig(player.getWorld().getProperties()).getConfig().claim.bankTaxSystem;
if (player.hasPermission(GDPermissions.DELETE_CLAIM_ADMIN)) {
isAdmin = true;
}
final MenuType lastFlagType = this.lastActiveMenuTypeMap.getIfPresent(player.getUniqueId());
if (lastFlagType != null && lastFlagType != displayType) {
PaginationUtil.getInstance().resetActivePage(player.getUniqueId());
}
final Component whiteOpenBracket = TextComponent.of("[", TextColor.AQUA);
final Component whiteCloseBracket = TextComponent.of("]", TextColor.AQUA);
final Component showOverrideText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("OVERRIDE", TextColor.RED)));
final Component showDefaultText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("DEFAULT", TextColor.LIGHT_PURPLE)));
final Component showClaimText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("CLAIM", TextColor.GOLD)));
final Component showInheritText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("INHERIT", TextColor.AQUA)));
Component defaultFlagText = TextComponent.empty();
if (isAdmin) {
defaultFlagText = TextComponent.builder("")
.append(displayType == MenuType.DEFAULT ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("DEFAULT", TextColor.LIGHT_PURPLE)
.append(whiteCloseBracket).build() : TextComponent.of("DEFAULT", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimOptionConsumer(src, claim, MenuType.DEFAULT))))
.hoverEvent(HoverEvent.showText(showDefaultText)).build();
}
final Component overrideFlagText = TextComponent.builder("")
.append(displayType == MenuType.OVERRIDE ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("OVERRIDE", TextColor.RED)
.append(whiteCloseBracket).build() : TextComponent.of("OVERRIDE", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimOptionConsumer(src, claim, MenuType.OVERRIDE))))
.hoverEvent(HoverEvent.showText(showOverrideText)).build();
final Component claimFlagText = TextComponent.builder("")
.append(displayType == MenuType.CLAIM ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("CLAIM", TextColor.YELLOW)
.append(whiteCloseBracket).build() : TextComponent.of("CLAIM", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimOptionConsumer(src, claim, MenuType.CLAIM))))
.hoverEvent(HoverEvent.showText(showClaimText)).build();
final Component inheritFlagText = TextComponent.builder("")
.append(displayType == MenuType.INHERIT ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("INHERIT", TextColor.AQUA)
.append(whiteCloseBracket).build() : TextComponent.of("INHERIT", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimOptionConsumer(src, claim, MenuType.INHERIT))))
.hoverEvent(HoverEvent.showText(showInheritText)).build();
Component claimOptionHead = TextComponent.empty();
if (this.subjectType == ClaimSubjectType.GLOBAL) {
if (isAdmin) {
claimOptionHead = TextComponent.builder("")
.append(" Displaying : ", TextColor.AQUA)
.append(defaultFlagText)
.append(" ")
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
} else {
claimOptionHead = TextComponent.builder("")
.append(" Displaying : ", TextColor.AQUA)
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
}
} else {
claimOptionHead = TextComponent.builder("")
.append(" " + this.subjectType.getFriendlyName() + " ", TextColor.AQUA)
.append(this.friendlySubjectName, TextColor.YELLOW)
.append(" : ", TextColor.AQUA)
.append(claimFlagText)
.append(" ")
.append(inheritFlagText)
.append(" ")
.append(overrideFlagText).build();
}
Set<Context> defaultContexts = new HashSet<>();
Set<Context> overrideContexts = new HashSet<>();
if (claim.isAdminClaim()) {
defaultContexts.add(ClaimContexts.ADMIN_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.ADMIN_OVERRIDE_CONTEXT);
} else if (claim.isBasicClaim() || claim.isSubdivision()) {
defaultContexts.add(ClaimContexts.BASIC_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.BASIC_OVERRIDE_CONTEXT);
} else if (claim.isTown()) {
defaultContexts.add(ClaimContexts.TOWN_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.TOWN_OVERRIDE_CONTEXT);
} else {
defaultContexts.add(ClaimContexts.WILDERNESS_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.WILDERNESS_OVERRIDE_CONTEXT);
}
defaultContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
overrideContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, OptionData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getTransientOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext()) || contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
}
}
if (displayType == MenuType.DEFAULT) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
for (Option option : OptionRegistryModule.getInstance().getAll()) {
boolean found = false;
for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) {
if (optionEntry.getValue().option == option) {
found = true;
break;
}
}
if (!found) {
filteredContextMap.put(option.getPermission(), new OptionData(option, "undefined", displayType, contexts));
}
}
}
if (displayType == MenuType.CLAIM) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
filteredContextMap.put(Options.PVP.getPermission(), new OptionData(Options.PVP, "undefined", MenuType.DEFAULT, contexts));
}
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
}
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
}
if (displayType != MenuType.DEFAULT) {
if (claim.isTown() || isAdmin) {
if (contextSet.contains(claim.getContext())) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.CLAIM, mapEntry.getValue());
}
}
if (contextSet.contains(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT)) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
}
if (contextSet.contains(claim.getOverrideClaimContext())) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
} else if (contextSet.contains(claim.getOverrideTypeContext())) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.OVERRIDE, mapEntry.getValue());
}
}
}
Map<Set<Context>, ClaimClickData> inheritPermissionMap = Maps.newHashMap();
final List<Claim> inheritParents = claim.getInheritedParents();
Collections.reverse(inheritParents);
for (Claim current : inheritParents) {
GDClaim currentClaim = (GDClaim) current;
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(currentClaim.getContext())) {
inheritPermissionMap.put(mapEntry.getKey(), new ClaimClickData(currentClaim, mapEntry.getValue()));
}
}
}
final Map<String, Map<Integer, Component>> textMap = new TreeMap<>();
for (Entry<String, OptionData> mapEntry : filteredContextMap.entrySet()) {
final OptionData optionData = mapEntry.getValue();
final Option option = optionData.option;
if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue;
}
for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) {
if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) {
continue;
}
final Set<Context> contexts = optionHolder.getAllContexts();
Component optionText = getClickableOptionComponent(src, claim, option, optionHolder, contexts, displayType);
final int hashCode = Objects.hash(option.getPermission(), contexts);
Map<Integer, Component> componentMap = textMap.get(option.getPermission());
if (componentMap == null) {
componentMap = new HashMap<>();
componentMap.put(hashCode, optionText);
textMap.put(option.getPermission(), componentMap);
} else {
componentMap.put(hashCode, optionText);
}
}
}
List<Component> textList = new ArrayList<>();
for (Entry<String, Map<Integer, Component>> mapEntry : textMap.entrySet()) {
textList.addAll(mapEntry.getValue().values());
}
Collections.sort(textList, UIHelper.PLAIN_COMPARATOR);
int fillSize = 20 - (textList.size() + 2);
for (int i = 0; i < fillSize; i++) {
textList.add(TextComponent.of(" "));
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(claimOptionHead).padding(TextComponent.builder(" ").decoration(TextDecoration.STRIKETHROUGH, true).build()).contents(textList);
final PaginationList paginationList = paginationBuilder.build();
Integer activePage = 1;
activePage = PaginationUtil.getInstance().getActivePage(player.getUniqueId());
if (activePage == null) {
activePage = 1;
}
this.lastActiveMenuTypeMap.put(player.getUniqueId(), displayType);
paginationList.sendTo(player, activePage);
}
private void addFilteredContexts(GDPermissionUser src, Map<String, OptionData> filteredContextMap, Set<Context> contexts, MenuType type, Map<String, String> permissions) {
final Player player = src.getOnlinePlayer();
final GDPlayerData playerData = src.getInternalPlayerData();
for (Map.Entry<String, String> permissionEntry : permissions.entrySet()) {
final Option option = OptionRegistryModule.getInstance().getById(permissionEntry.getKey()).orElse(null);
if (option == null) {
continue;
}
if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue;
}
if (option.isGlobal()) {
if (!player.hasPermission(GDPermissions.MANAGE_GLOBAL_OPTIONS +"." + option.getName().toLowerCase())) {
continue;
}
} else if (((GDOption) option).isAdmin()) {
if (!player.hasPermission(GDPermissions.MANAGE_ADMIN_OPTIONS +"." + option.getName().toLowerCase())) {
continue;
}
} else {
if (!player.hasPermission(GDPermissions.USER_CLAIM_OPTIONS +"." + option.getName().toLowerCase())) {
continue;
}
}
final OptionData optionData = filteredContextMap.get(permissionEntry.getKey());
if (optionData != null) {
optionData.addContexts(option, permissionEntry.getValue(), type, contexts);
} else {
filteredContextMap.put(permissionEntry.getKey(), new OptionData(option, permissionEntry.getValue(), type, contexts));
}
}
}
private Component getClickableOptionComponent(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set<Context> contexts, MenuType displayType) {
final Player player = src.getOnlinePlayer();
final GDPlayerData playerData = src.getInternalPlayerData();
boolean hasEditPermission = true;
Component hoverEventText = TextComponent.empty();
final MenuType flagType = optionHolder.getType();
if (flagType == MenuType.DEFAULT) {
if (!playerData.canManageGlobalOptions) {
hoverEventText = MessageCache.getInstance().PERMISSION_OPTION_DEFAULTS;
hasEditPermission = false;
}
} else if (flagType == MenuType.OVERRIDE) {
if (!playerData.canManageOverrideOptions) {
hoverEventText = MessageCache.getInstance().PERMISSION_OPTION_OVERRIDES;
hasEditPermission = false;
}
} else if (flagType == MenuType.INHERIT) {
hoverEventText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_UI_INHERIT_PARENT,
ImmutableMap.of("name", claim.getFriendlyNameType()));
hasEditPermission = false;
}
if (displayType == MenuType.CLAIM) {
Component denyReason = claim.allowEdit(player);
if (denyReason != null) {
hoverEventText = denyReason;
hasEditPermission = false;
} else {
if (option.isGlobal()) {
if (!player.hasPermission(GDPermissions.MANAGE_GLOBAL_OPTIONS +"." + option.getName().toLowerCase())) {
hoverEventText = MessageCache.getInstance().PERMISSION_OPTION_USE;
hasEditPermission = false;
}
} else if (((GDOption) option).isAdmin()) {
if (!player.hasPermission(GDPermissions.MANAGE_ADMIN_OPTIONS +"." + option.getName().toLowerCase())) {
hoverEventText = MessageCache.getInstance().PERMISSION_OPTION_USE;
hasEditPermission = false;
}
}
else {
if (!player.hasPermission(GDPermissions.USER_CLAIM_OPTIONS +"." + option.getName().toLowerCase())) {
hoverEventText = MessageCache.getInstance().PERMISSION_OPTION_USE;
hasEditPermission = false;
}
}
}
}
final boolean customContexts = UIHelper.containsCustomContext(contexts);
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor();
boolean isNumber = false;
if (option.getAllowedType().isAssignableFrom(Integer.class) || option.getAllowedType().isAssignableFrom(Double.class)) {
isNumber = true;
}
TextComponent.Builder builder = null;
if (isNumber && hasEditPermission) {
builder = TextComponent.builder()
.append(getOptionText(option, contexts))
.append(" ")
.append(TextComponent.builder()
.append(TextComponent.of("< ").decoration(TextDecoration.BOLD, true))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, true)))))
.append(currentValue.toLowerCase(), color);
} else {
builder = TextComponent.builder()
.append(getOptionText(option, contexts))
.append(" ")
.append(TextComponent.builder()
.append(currentValue.toLowerCase(), color)
.hoverEvent(HoverEvent.showText(hoverEventText)));
}
if (hasEditPermission) {
if (!option.getAllowedType().isAssignableFrom(Integer.class) && !option.getAllowedType().isAssignableFrom(Double.class)) {
builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} else {
builder.append(TextComponent.builder()
.append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false)))));
}
if (option.getAllowedType().isAssignableFrom(String.class)) {
builder.clickEvent(createClickEvent(player, option));
}
}
if (displayType == MenuType.DEFAULT) {
builder.hoverEvent(HoverEvent.showText(TextComponent.builder().append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_SET,
ImmutableMap.of(
"option", TextComponent.of(option.getName().toLowerCase()).color(TextColor.GREEN),
"value", TextComponent.of(currentValue).color(TextColor.GOLD)))).build()));
}
return builder.build();
}
private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) {
return true;
}
}
return false;
}
private ClickEvent createClickEvent(Player src, Option option) {
return ClickEvent.suggestCommand("/gd option " + option.getName() + " ");
}
private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set<Context> contexts, MenuType displayType, boolean leftArrow) {
final String currentValue = optionHolder.getValue();
return consumer -> {
String newValue = "";
if (option.getAllowedType().isAssignableFrom(Tristate.class)) {
Tristate value = getMenuTypeValue(TypeToken.of(Tristate.class), currentValue);
if (value == Tristate.TRUE) {
newValue = "false";
} else if (value == Tristate.FALSE) {
newValue = "undefined";
} else {
newValue = "true";
}
}
if (option.getAllowedType().isAssignableFrom(Boolean.class)) {
Boolean value = getMenuTypeValue(TypeToken.of(Boolean.class), currentValue);
Tristate result = Tristate.UNDEFINED;
if (displayType == MenuType.DEFAULT || (displayType == MenuType.CLAIM && optionHolder.getType() == MenuType.DEFAULT)) {
result = Tristate.fromBoolean(!value);
} else {
// Always fall back to transient default
result = Tristate.UNDEFINED;
}
newValue = result.toString().toLowerCase();
}
if (option.getAllowedType().isAssignableFrom(GameModeType.class)) {
GameModeType value = getMenuTypeValue(TypeToken.of(GameModeType.class), currentValue);
if (value == null || value == GameModeTypes.UNDEFINED) {
newValue = "adventure";
} else if (value == GameModeTypes.ADVENTURE) {
newValue = "creative";
} else if (value == GameModeTypes.CREATIVE) {
newValue = "survival";
} else if (value == GameModeTypes.SURVIVAL) {
newValue = "spectator";
} else {
newValue = "undefined";
}
}
if (option.getAllowedType().isAssignableFrom(CreateModeType.class)) {
CreateModeType value = getMenuTypeValue(TypeToken.of(CreateModeType.class), currentValue);
if (value == null || value == CreateModeTypes.UNDEFINED) {
newValue = "area";
} else if (value == CreateModeTypes.AREA) {
newValue = "volume";
} else {
newValue = "undefined";
}
}
if (option.getAllowedType().isAssignableFrom(WeatherType.class)) {
WeatherType value = getMenuTypeValue(TypeToken.of(WeatherType.class), currentValue);
if (value == null || value == WeatherTypes.UNDEFINED) {
newValue = "clear";
} else if (value == WeatherTypes.CLEAR) {
newValue = "rain";
} else {
newValue = "undefined";
}
}
if (option.getAllowedType().isAssignableFrom(Integer.class)) {
Integer value = getMenuTypeValue(TypeToken.of(Integer.class), currentValue);
if (leftArrow) {
if (value == null || value < 1) {
TextAdapter.sendComponent(src.getOnlinePlayer(), TextComponent.of("This value is NOT defined and cannot go any lower."));
} else {
if ((option == Options.MIN_LEVEL || option == Options.MAX_LEVEL || option == Options.MIN_SIZE_Y || option == Options.MAX_SIZE_Y) && value == 1) {
value = null;
} else {
value -= 1;
if (value <= 0) {
if (option == Options.MAX_LEVEL) {
value = 255;
}
}
}
}
} else {
if (value == null) {
value = 1;
} else {
if ((option == Options.MIN_SIZE_Y || option == Options.MAX_SIZE_Y) && value == 256) {
value = null;
} else if ((option == Options.MIN_LEVEL || option == Options.MAX_LEVEL) && value == 255) {
value = null;
} else {
value += 1;
}
}
}
newValue = value == null ? "undefined" :String.valueOf(value);
}
if (option.getAllowedType().isAssignableFrom(Double.class)) {
Double value = getMenuTypeValue(TypeToken.of(Double.class), currentValue);
if (leftArrow) {
if (value == null || value < 1) {
TextAdapter.sendComponent(src.getOnlinePlayer(), TextComponent.of("This value is NOT defined and cannot go any lower."));
} else {
value -= 1;
if (option == Options.ABANDON_RETURN_RATIO && value <= 0) {
value = null;
} else {
if (value < 0) {
value = 0.0;
}
}
}
} else {
if (value == null) {
value = 1.0;
} else {
value += 1;
}
}
newValue = value == null ? "undefined" :String.valueOf(value);
}
Set<Context> newContexts = new HashSet<>();
final boolean isCustom = UIHelper.containsCustomContext(contexts);
if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext());
} else {
newContexts.addAll(contexts);
}
// Remove server context
final Iterator<Context> iterator = newContexts.iterator();
while (iterator.hasNext()) {
final Context context = iterator.next();
if (context.getKey().equals("server")) {
iterator.remove();
}
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts);
showOptionPermissions(src, claim, displayType);
};
}
private Consumer<CommandSource> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> {
String newValue = "";
final Set<Context> filteredContexts = applySelectedTypeContext(claim, menuType, contexts);
if (option.getAllowedType().isAssignableFrom(Boolean.class)) {
Boolean value = getMenuTypeValue(TypeToken.of(Boolean.class), currentValue);
if (value == null) {
newValue = "true";
} else if (value) {
newValue = "false";
} else {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
if (option.getAllowedType().isAssignableFrom(Integer.class)) {
newValue = getMenuTypeValue(TypeToken.of(String.class), currentValue);
if (newValue == null) {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
showOptionPermissions(src, claim, menuType);
};
}
private Set<Context> applySelectedTypeContext(Claim claim, MenuType menuType, Set<Context> contexts) {
Set<Context> filteredContexts = new HashSet<>(contexts);
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
filteredContexts.remove(context);
}
}
if (menuType == MenuType.DEFAULT) {
filteredContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
}
if (menuType == MenuType.CLAIM) {
filteredContexts.add(claim.getContext());
}
if (menuType == MenuType.OVERRIDE) {
filteredContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
}
return filteredContexts;
}
private boolean contextsMatch(Set<Context> contexts, Set<Context> newContexts) {
// first filter out gd claim contexts
final Set<Context> filteredContexts = new HashSet<>();
final Set<Context> filteredNewContexts = new HashSet<>();
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredContexts.add(context);
}
for (Context context : newContexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredNewContexts.add(context);
}
return Objects.hash(filteredContexts) == Objects.hash(filteredNewContexts);
}
private static Set<Context> createClaimContextSet(GDClaim claim, Set<Context> contexts) {
Set<Context> claimContexts = new HashSet<>();
claimContexts.add(claim.getContext());
for (Context context : contexts) {
if (context.getKey().contains("world") || context.getKey().contains("gd_claim")) {
continue;
}
claimContexts.add(context);
}
return claimContexts;
}
private static Component getOptionText(Option option, Set<Context> contexts) {
boolean customContext = UIHelper.containsCustomContext(contexts);
final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder()
.append(option.getDescription())
.build())).build();
return optionText;
}
private static <T> T getMenuTypeValue(TypeToken<T> type, String value) {
if (type.getRawType().isAssignableFrom(Double.class)) {
Double newValue = null;
try {
newValue = Double.valueOf(value);
} catch (NumberFormatException e) {
return null;
}
return (T) newValue;
}
if (type.getRawType().isAssignableFrom(Integer.class)) {
Integer newValue = null;
try {
newValue = Integer.valueOf(value);
} catch (NumberFormatException e) {
return null;
}
return (T) newValue;
}
if (type.getRawType().isAssignableFrom(String.class)) {
return (T) value;
}
if (type.getRawType().isAssignableFrom(Boolean.class)) {
if (value.equalsIgnoreCase("false")) {
return (T) Boolean.valueOf(value);
} else if (value.equalsIgnoreCase("true")) {
return (T) Boolean.valueOf(value);
}
}
if (type.getRawType().isAssignableFrom(Tristate.class)) {
if (value.equalsIgnoreCase("undefined")) {
return (T) Tristate.UNDEFINED;
}
if (value.equalsIgnoreCase("true")) {
return (T) Tristate.TRUE;
}
if (value.equalsIgnoreCase("false")) {
return (T) Tristate.FALSE;
}
int permValue = 0;
try {
permValue = Integer.parseInt(value);
} catch (NumberFormatException e) {
return (T) Tristate.UNDEFINED;
}
if (permValue == 0) {
return (T) Tristate.UNDEFINED;
}
return (T) (permValue == 1 ? Tristate.TRUE : Tristate.FALSE);
}
if (type.getRawType().isAssignableFrom(GameModeType.class)) {
if (value.equalsIgnoreCase("undefined")) {
return (T) GameModeTypes.UNDEFINED;
}
if (value.equalsIgnoreCase("adventure")) {
return (T) GameModeTypes.ADVENTURE;
}
if (value.equalsIgnoreCase("creative")) {
return (T) GameModeTypes.CREATIVE;
}
if (value.equalsIgnoreCase("survival")) {
return (T) GameModeTypes.SURVIVAL;
}
if (value.equalsIgnoreCase("spectator")) {
return (T) GameModeTypes.SPECTATOR;
}
}
if (type.getRawType().isAssignableFrom(WeatherType.class)) {
if (value.equalsIgnoreCase("undefined")) {
return (T) WeatherTypes.UNDEFINED;
}
if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR;
}
if (value.equalsIgnoreCase("rain")) {
return (T) WeatherTypes.RAIN;
}
}
if (type.getRawType().isAssignableFrom(CreateModeType.class)) {
if (value.equalsIgnoreCase("undefined")) {
return (T) CreateModeTypes.UNDEFINED;
}
if (value.equalsIgnoreCase("area")) {
return (T) CreateModeTypes.AREA;
}
if (value.equalsIgnoreCase("volume")) {
return (T) CreateModeTypes.VOLUME;
}
}
return null;
}
private Consumer<CommandSource> createClaimOptionConsumer(GDPermissionUser src, GDClaim claim, MenuType optionType) {
return consumer -> {
showOptionPermissions(src, claim, optionType);
};
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
public enum ClaimSubjectType {
GLOBAL("Global"),
GROUP("Group"),
PLAYER("Player");
private String friendlyName;
private ClaimSubjectType(String name) {
this.friendlyName = name;
}
public String getFriendlyName() {
return this.friendlyName;
}
}

View File

@ -0,0 +1,90 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.world.storage.WorldProperties;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_ACCRUED_CLAIM_BLOCKS)
public class CommandAdjustBonusClaimBlocks extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("acb|adjustclaimblocks")
@Description("Updates a player's accrued claim block total")
@Syntax("<player> <amount>")
@Subcommand("player adjustbonusblocks")
public void execute(CommandSource src, User user, int amount, @Optional String world) {
WorldProperties worldProperties = world == null ? null : Sponge.getServer().getWorldProperties(world).orElse(null);
if (worldProperties == null) {
if (src instanceof Player) {
worldProperties = ((Player) src).getWorld().getProperties();
} else {
worldProperties = Sponge.getServer().getDefaultWorld().get();
}
}
if (worldProperties == null || !GriefDefenderPlugin.getInstance().claimsEnabledForWorld(worldProperties.getUniqueId())) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// parse the adjustment amount
int adjustment = amount;
//User user = args.<User>getOne("user").get();
// give blocks to player
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(worldProperties.getUniqueId(), user.getUniqueId());
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + adjustment);
playerData.getStorageData().save();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_SUCCESS, ImmutableMap.of(
"player", user.getName(),
"amount", adjustment,
"total", playerData.getBonusClaimBlocks()));
TextAdapter.sendComponent(src, message);
GriefDefenderPlugin.getInstance().getLogger().info(
src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + adjustment + ".");
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.Description;
import com.griefdefender.text.action.GDCallbackHolder;
import org.spongepowered.api.command.CommandSource;
import java.util.UUID;
import java.util.function.Consumer;
public class CommandCallback extends BaseCommand {
@CommandAlias("gd:callback")
@Description("Execute a callback registered as part of a Text object. Primarily for internal use")
public void execute(CommandSource src, String[] args) {
final UUID callbackId = UUID.fromString(args[0]);
Consumer<CommandSource> callback = GDCallbackHolder.getInstance().getCallbackForUUID(callbackId).orElse(null);
if (callback != null) {
callback.accept(src);
}
}
}

View File

@ -0,0 +1,218 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.transaction.ResultType;
import org.spongepowered.api.service.economy.transaction.TransactionResult;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_ABANDON_BASIC)
public class CommandClaimAbandon extends BaseCommand {
protected boolean abandonTopClaim = false;
@CommandAlias("abandon|abandonclaim")
@Description("Abandons a claim")
@Subcommand("abandon claim")
public void execute(Player player) {
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
final UUID ownerId = claim.getOwnerUniqueId();
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPlayerData playerData = user.getInternalPlayerData();
final boolean isAdmin = playerData.canIgnoreClaim(claim);
final boolean isTown = claim.isTown();
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ABANDON_CLAIM_MISSING);
return;
} else if (!isAdmin && !player.getUniqueId().equals(ownerId) && claim.isUserTrusted(player, TrustTypes.MANAGER)) {
if (claim.parent == null) {
// Managers can only abandon child claims
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
} else if (!isAdmin && (claim.allowEdit(player) != null || (!claim.isAdminClaim() && !player.getUniqueId().equals(ownerId)))) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
} else {
if (this.abandonTopClaim && claim.children.size() > 0) {
if (claim.isTown() || claim.isAdminClaim()) {
Set<Claim> invalidClaims = new HashSet<>();
for (Claim child : claim.getChildren(true)) {
if (child.getOwnerUniqueId() == null || !child.getOwnerUniqueId().equals(ownerId)) {
//return CommandResult.empty();
invalidClaims.add(child);
}
}
if (!invalidClaims.isEmpty()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ABANDON_TOWN_CHILDREN);
CommandHelper.showClaims(player, invalidClaims, 0, true);
return;
}
}
}
}
final int abandonDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), user, Options.ABANDON_DELAY, claim);
if (abandonDelay > 0) {
final Instant localNow = Instant.now();
final Instant dateCreated = claim.getInternalClaimData().getDateCreated();
final Instant delayExpires = dateCreated.plus(Duration.ofDays(abandonDelay));
final boolean delayActive = !delayExpires.isBefore(localNow);
if (delayActive) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.ABANDON_CLAIM_DELAY_WARNING,
ImmutableMap.of("date", Date.from(delayExpires))));
return;
}
}
final boolean autoSchematicRestore = GriefDefenderPlugin.getActiveConfig(player.getWorld().getProperties()).getConfig().claim.claimAutoSchematicRestore;
final Component confirmationText = TextComponent.builder()
.append(autoSchematicRestore ? MessageCache.getInstance().SCHEMATIC_ABANDON_RESTORE_WARNING : MessageCache.getInstance().ABANDON_WARNING)
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(player, playerData, claim, this.abandonTopClaim))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(player, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player player, GDPlayerData playerData, GDClaim claim, boolean abandonTopClaim) {
return confirm -> {
GDCauseStackManager.getInstance().pushCause(player);
GDRemoveClaimEvent.Abandon event = new GDRemoveClaimEvent.Abandon(claim);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageCache.getInstance().PLUGIN_EVENT_CANCEL));
return;
}
if (!claim.isSubdivision() && !claim.isAdminClaim()) {
if (GriefDefenderPlugin.getGlobalConfig().getConfig().economy.economyMode) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null);
if (playerAccount == null) {
return;
}
}
}
GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(player.getWorld().getUniqueId());
playerData.useRestoreSchematic = event.isRestoring();
final ClaimResult claimResult = claimManager.deleteClaimInternal(claim, abandonTopClaim);
playerData.useRestoreSchematic = false;
if (!claimResult.successful()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_FAILED,
ImmutableMap.of("result", claimResult.getMessage().orElse(TextComponent.of(claimResult.getResultType().toString()))))));
return;
}
// remove all context permissions
PermissionUtil.getInstance().clearPermissions(claim);
playerData.revertActiveVisual(player);
if (claim.isTown()) {
playerData.inTown = false;
playerData.townChat = false;
}
if (!claim.isSubdivision() && !claim.isAdminClaim()) {
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), player, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null);
if (playerAccount == null) {
return;
}
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final double requiredClaimBlocks = claim.getClaimBlocks() * abandonReturnRatio;
final double refund = requiredClaimBlocks * claim.getOwnerEconomyBlockCost();
final TransactionResult result = playerAccount.deposit(defaultCurrency, BigDecimal.valueOf(refund), Sponge.getCauseStackManager().getCurrentCause());
if (result.getResult() == ResultType.SUCCESS) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_ABANDON_SUCCESS, ImmutableMap.of(
"amount", refund));
GriefDefenderPlugin.sendMessage(player, message);
}
} else {
int newAccruedClaimCount = playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getClaimBlocks() * (1 - abandonReturnRatio)));
playerData.setAccruedClaimBlocks(newAccruedClaimCount);
int remainingBlocks = playerData.getRemainingClaimBlocks();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_SUCCESS, ImmutableMap.of(
"amount", remainingBlocks));
GriefDefenderPlugin.sendMessage(player, message);
}
}
};
}
}

View File

@ -0,0 +1,188 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.transaction.ResultType;
import org.spongepowered.api.service.economy.transaction.TransactionResult;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_ABANDON_ALL_CLAIMS)
public class CommandClaimAbandonAll extends BaseCommand {
@CommandAlias("abandonall|abandonallclaims")
@Description("Abandons ALL your claims")
@Subcommand("abandon all")
public void execute(Player player) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
int originalClaimCount = user.getInternalPlayerData().getInternalClaims().size();
if (originalClaimCount == 0) {
try {
throw new CommandException(MessageCache.getInstance().CLAIM_NO_CLAIMS);
} catch (CommandException e) {
TextAdapter.sendComponent(player, e.getText());
return;
}
}
final boolean autoSchematicRestore = GriefDefenderPlugin.getActiveConfig(player.getWorld().getUniqueId()).getConfig().claim.claimAutoSchematicRestore;
final Component confirmationText = TextComponent.builder()
.append(autoSchematicRestore ? MessageCache.getInstance().SCHEMATIC_ABANDON_ALL_RESTORE_WARNING : MessageCache.getInstance().ABANDON_ALL_WARNING)
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(user))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(player, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(GDPermissionUser user) {
return confirm -> {
Set<Claim> allowedClaims = new HashSet<>();
Set<Claim> delayedClaims = new HashSet<>();
final int abandonDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), user, Options.ABANDON_DELAY);
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
for (Claim claim : playerData.getInternalClaims()) {
if (abandonDelay > 0) {
final Instant localNow = Instant.now();
final Instant dateCreated = ((GDClaim) claim).getInternalClaimData().getDateCreated();
final Instant dateExpires = dateCreated.plus(Duration.ofDays(abandonDelay));
final boolean delayActive = !dateExpires.isBefore(localNow);
if (delayActive) {
delayedClaims.add(claim);
} else {
allowedClaims.add(claim);
}
} else {
allowedClaims.add(claim);
}
}
if (!allowedClaims.isEmpty()) {
GDCauseStackManager.getInstance().pushCause(user);
GDRemoveClaimEvent.Abandon event = new GDRemoveClaimEvent.Abandon(ImmutableList.copyOf(allowedClaims));
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(user.getOnlinePlayer(), event.getMessage().orElse(MessageCache.getInstance().PLUGIN_EVENT_CANCEL).color(TextColor.RED));
return;
}
double refund = 0;
// adjust claim blocks
for (Claim claim : allowedClaims) {
// remove all context permissions
PermissionUtil.getInstance().clearPermissions((GDClaim) claim);
if (claim.isSubdivision() || claim.isAdminClaim() || claim.isWilderness()) {
continue;
}
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
refund += claim.getClaimBlocks() * abandonReturnRatio;
} else {
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getClaimBlocks() * (1 - abandonReturnRatio))));
}
}
playerData.useRestoreSchematic = event.isRestoring();
GriefDefenderPlugin.getInstance().dataStore.abandonClaimsForPlayer(user, allowedClaims);
playerData.useRestoreSchematic = false;
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null);
if (playerAccount == null) {
return;
}
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final TransactionResult result = playerAccount.deposit(defaultCurrency, BigDecimal.valueOf(refund), Sponge.getCauseStackManager().getCurrentCause());
if (result.getResult() == ResultType.SUCCESS) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_ABANDON_SUCCESS, ImmutableMap.of(
"amount", TextComponent.of(String.valueOf(refund))));
GriefDefenderPlugin.sendMessage(player, message);
}
} else {
int remainingBlocks = playerData.getRemainingClaimBlocks();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_SUCCESS, ImmutableMap.of(
"amount", remainingBlocks));
TextAdapter.sendComponent(player, message);
}
playerData.revertActiveVisual(player);
}
if (!delayedClaims.isEmpty()) {
TextAdapter.sendComponent(player, MessageCache.getInstance().ABANDON_ALL_DELAY_WARNING);
CommandHelper.showClaims(player, delayedClaims, 0, true);
}
};
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_ABANDON_TOP_LEVEL_CLAIM)
public class CommandClaimAbandonTop extends CommandClaimAbandon {
public CommandClaimAbandonTop() {
this.abandonTopClaim = true;
}
@CommandAlias("abandontop")
@Description("Abandons top level claim")
@Subcommand("abandon top")
public void execute(Player player) {
super.execute(player);
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_ADMIN_CLAIMS)
public class CommandClaimAdmin extends BaseCommand {
@CommandAlias("modeadmin|adminclaims|ac")
@Description("Switches the shovel tool to administrative claims mode")
@Subcommand("mode admin")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.shovelMode = ShovelTypes.ADMIN;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().MODE_ADMIN);
}
}

View File

@ -0,0 +1,129 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.item.inventory.ItemStack;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.registry.BlockTypeRegistryModule;
import com.griefdefender.internal.registry.EntityTypeRegistryModule;
import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.permission.GDPermissions;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BAN)
public class CommandClaimBan extends BaseCommand {
@CommandCompletion("@gdbantypes @gdmcids @gddummy")
@CommandAlias("claimban")
@Description("Bans target id from all usage.")
@Syntax("hand | <type> <target> [<message>]")
@Subcommand("ban")
public void execute(Player player, String type, @Optional String id, @Optional String message) {
Component component = null;
if (type.equalsIgnoreCase("block")) {
if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_BLOCK_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
if (message == null) {
component = TextComponent.empty();
} else {
component = LegacyComponentSerializer.legacy().deserialize(message, '&');
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.addBlockBan(id, component);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_BLOCK,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("entity")) {
if (!EntityTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_ENTITY_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
if (message == null) {
component = TextComponent.empty();
} else {
component = LegacyComponentSerializer.legacy().deserialize(message, '&');
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.addEntityBan(id, component);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ENTITY,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("item")) {
if (!ItemTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_ITEM_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
if (message == null) {
component = TextComponent.empty();
} else {
component = LegacyComponentSerializer.legacy().deserialize(message, '&');
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.addItemBan(id, component);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("hand")) {
final ItemStack itemInHand = player.getItemInHand(HandTypes.MAIN_HAND).orElse(null);
if (itemInHand == null) {
return;
}
final String handItemId = itemInHand.getType().getId();
if (message == null) {
component = TextComponent.empty();
} else {
component = LegacyComponentSerializer.legacy().deserialize(message, '&');
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.addItemBan(handItemId, component);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(handItemId, TextColor.LIGHT_PURPLE))));
}
if (component == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE,
ImmutableMap.of("type", type)));
}
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BANK)
public class CommandClaimBank extends BaseCommand {
protected boolean townOnly = false;
@CommandAlias("claimbank")
@Description("Used for claim bank queries")
@Syntax("<withdraw|deposit> <amount>")
@Subcommand("claim bank")
public void execute(Player player, @Optional String[] args) throws CommandException {
if (!GriefDefenderPlugin.getActiveConfig(player.getWorld().getProperties()).getConfig().claim.bankTaxSystem) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().BANK_TAX_SYSTEM_DISABLED);
return;
}
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (this.townOnly) {
if (!claim.isInTown()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_NOT_IN);
return;
}
claim = claim.getTownClaim();
} else {
if (claim.isSubdivision() || claim.isAdminClaim()) {
return;
}
}
if (args.length == 0 || args.length < 2) {
CommandHelper.displayClaimBankInfo(player, claim);
return;
}
CommandHelper.handleBankTransaction(player, args, claim);
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_BASIC_MODE)
public class CommandClaimBasic extends BaseCommand {
@CommandAlias("modebasic|basicclaims|bc")
@Description("Switches the shovel tool back to basic claims mode")
@Subcommand("mode basic")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.shovelMode = ShovelTypes.BASIC;
playerData.claimSubdividing = null;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().MODE_BASIC);
}
}

View File

@ -0,0 +1,97 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.economy.account.Account;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BUY)
public class CommandClaimBuy extends BaseCommand {
@CommandAlias("claimbuy")
@Description("List all claims available for purchase.\nNote: Requires economy plugin.")
@Subcommand("buy claim")
public void execute(Player player) {
if (!GriefDefenderPlugin.getInstance().economyService.isPresent()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_NOT_INSTALLED);
return;
}
Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(player.getUniqueId()).orElse(null);
if (playerAccount == null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_PLAYER_NOT_FOUND, ImmutableMap.of(
"player", player.getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
Set<Claim> claimsForSale = new HashSet<>();
GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(player.getWorld().getUniqueId());
for (Claim worldClaim : claimManager.getWorldClaims()) {
if (worldClaim.isWilderness()) {
continue;
}
if (!worldClaim.isAdminClaim() && worldClaim.getEconomyData().isForSale() && worldClaim.getEconomyData().getSalePrice() > -1) {
claimsForSale.add(worldClaim);
}
for (Claim child : worldClaim.getChildren(true)) {
if (child.isAdminClaim()) {
continue;
}
if (child.getEconomyData().isForSale() && child.getEconomyData().getSalePrice() > -1) {
claimsForSale.add(child);
}
}
}
List<Component> claimsTextList = CommandHelper.generateClaimTextListCommand(new ArrayList<Component>(), claimsForSale, player.getWorld().getName(), null, player, CommandHelper.createCommandConsumer(player, "claimbuy", ""), false);
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(MessageCache.getInstance().COMMAND_CLAIMBUY_TITLE).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(claimsTextList);
paginationBuilder.sendTo(player);
return;
}
}

View File

@ -0,0 +1,143 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.transaction.ResultType;
import org.spongepowered.api.service.economy.transaction.TransactionResult;
import java.math.BigDecimal;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_BUY_CLAIM_BLOCKS)
public class CommandClaimBuyBlocks extends BaseCommand {
@CommandAlias("buyclaim|buyclaimblocks|buyblocks")
@Description("Purchases additional claim blocks with server money.\nNote: Requires economy plugin.")
@Syntax("[<amount>]")
@Subcommand("buy blocks")
public void execute(Player player, @Optional Integer blockCount) {
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_NOT_AVAILABLE_ECONOMY);
return;
}
if (!GriefDefenderPlugin.getInstance().economyService.isPresent()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_NOT_INSTALLED);
return;
}
Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(player.getUniqueId()).orElse(null);
if (playerAccount == null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_PLAYER_NOT_FOUND, ImmutableMap.of(
"player", player.getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
final double economyBlockCost = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), player, Options.ECONOMY_BLOCK_COST);
final double economyBlockSell = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), player, Options.ECONOMY_BLOCK_SELL_RETURN);
if (economyBlockCost == 0 && economyBlockSell == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_BUY_SELL_DISABLED);
return;
}
if (economyBlockCost == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_ONLY_SELL);
return;
}
double balance = playerAccount.getBalance(GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency()).doubleValue();
if (blockCount == null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_PURCHASE_COST, ImmutableMap.of(
"amount", economyBlockCost,
"balance", String.valueOf("$" + balance)));
GriefDefenderPlugin.sendMessage(player, message);
return;
} else {
if (blockCount <= 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_BUY_INVALID);
return;
}
final double totalCost = blockCount * economyBlockCost;
final int newClaimBlockTotal = playerData.getAccruedClaimBlocks() + blockCount;
if (newClaimBlockTotal > playerData.getMaxAccruedClaimBlocks()) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_PURCHASE_LIMIT, ImmutableMap.of(
"total", newClaimBlockTotal,
"limit", playerData.getMaxAccruedClaimBlocks()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
try (final CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().addContext(GriefDefenderPlugin.PLUGIN_CONTEXT, GriefDefenderPlugin.getInstance());
TransactionResult transactionResult = playerAccount.withdraw
(GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency(), BigDecimal.valueOf(totalCost),
Sponge.getCauseStackManager().getCurrentCause());
if (transactionResult.getResult() != ResultType.SUCCESS) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_WITHDRAW_ERROR, ImmutableMap.of(
"reason", transactionResult.getResult()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
}
final int bonusTotal = playerData.getBonusClaimBlocks();
playerData.setBonusClaimBlocks(bonusTotal + blockCount);
playerData.getStorageData().save();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_PURCHASE_CONFIRMATION, ImmutableMap.of(
"amount", totalCost,
"balance", playerData.getRemainingClaimBlocks()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -0,0 +1,173 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.IEntityOwnable;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.living.Villager;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.World;
import org.spongepowered.common.SpongeImplHooks;
import org.spongepowered.common.entity.SpongeEntityType;
import java.util.UUID;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_CLEAR)
public class CommandClaimClear extends BaseCommand {
@CommandCompletion("@gdentityids @gddummy")
@CommandAlias("claimclear")
@Description("Allows clearing of entities within one or more claims.")
@Syntax("<entity_id> [claim_uuid]")
@Subcommand("claim clear")
public void execute(Player player, String target, @Optional String claimId) {
World world = player.getWorld();
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
UUID claimUniqueId = null;
GDClaim targetClaim = null;
if (claimId == null) {
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
final Component result = targetClaim.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
claimUniqueId = targetClaim.getUniqueId();
} else {
if (!player.hasPermission(GDPermissions.COMMAND_DELETE_CLAIMS)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CLAIMCLEAR_UUID_DENY);
return;
}
try {
claimUniqueId = UUID.fromString(claimId);
} catch (IllegalArgumentException e) {
return;
}
}
if (targetClaim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_ACTION_NOT_AVAILABLE,
ImmutableMap.of("type", TextComponent.of("the wilderness"))));
return;
}
// Unfortunately this is required until Pixelmon registers their entities correctly in FML
// If target was not found in registry, assume its a pixelmon animal
EntityType entityType = Sponge.getRegistry().getType(EntityType.class, target).orElse(null);
boolean isPixelmonAnimal = target.contains("pixelmon") && entityType == null;
int count = 0;
String[] parts = target.split(":");
String modId = "minecraft";
EnumCreatureType creatureType = null;
if (parts.length > 1) {
modId = parts[0];
creatureType = NMSUtil.SPAWN_TYPES.get(parts[1]);
} else {
creatureType = NMSUtil.SPAWN_TYPES.get(parts[0]);
if (creatureType == null) {
target = "minecraft:" + target;
}
}
for (Entity entity : world.getEntities()) {
net.minecraft.entity.Entity mcEntity = (net.minecraft.entity.Entity) entity;
if (entity instanceof Villager) {
continue;
}
if (entity instanceof IEntityOwnable) {
IEntityOwnable ownable = (IEntityOwnable) entity;
if (ownable.getOwnerId() != null) {
continue;
}
}
if (isPixelmonAnimal) {
if (parts[1].equalsIgnoreCase(mcEntity.getName().toLowerCase())) {
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation());
if (claim != null && claim.getUniqueId().equals(claimUniqueId)) {
mcEntity.setDead();
count++;
}
}
} else if (creatureType != null && SpongeImplHooks.isCreatureOfType(mcEntity, creatureType)) {
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation());
if (claim != null && claim.getUniqueId().equals(claimUniqueId)) {
// check modId
String mod = ((SpongeEntityType) entity.getType()).getModId();
if (modId.equalsIgnoreCase(mod)) {
mcEntity.setDead();
count++;
}
}
} else {
if (entityType == null || !entityType.equals(((SpongeEntityType) entity.getType()))) {
continue;
}
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation());
if (claim != null && claim.getUniqueId().equals(claimUniqueId)) {
mcEntity.setDead();
count++;
}
}
}
if (count == 0) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_CLAIMCLEAR_NO_ENTITIES,
ImmutableMap.of("type", TextComponent.of(target, TextColor.GREEN))));
} else {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_CLAIMCLEAR_NO_ENTITIES,
ImmutableMap.of(
"amount", count,
"type", TextComponent.of(target, TextColor.GREEN))));
}
}
}

View File

@ -0,0 +1,201 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.util.Direction;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PlayerUtil;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_EXPAND)
public class CommandClaimContract extends BaseCommand {
@CommandCompletion("@gddummy @gdblockfaces @gddummy")
@CommandAlias("claimcontract|contractclaim")
@Description("Contracts/Shrinks the claim from the direction you are facing.")
@Syntax("<amount> [direction]")
@Subcommand("claim contract")
public void execute(Player player, int amount, @Optional String direction) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(user.getInternalPlayerData(), player.getLocation());
final GDPlayerData playerData = user.getInternalPlayerData();
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
if (!claim.getInternalClaimData().isResizable() || (!claim.getOwnerUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_RESIZE);
return;
}
final Vector3i lesser = claim.lesserBoundaryCorner;
final Vector3i greater = claim.greaterBoundaryCorner;
Vector3i point1 = null;
Vector3i point2 = null;
if (direction == null || !direction.equalsIgnoreCase("all")) {
final Direction face = direction == null ? PlayerUtil.getInstance().getBlockFace(player) : PlayerUtil.getInstance().getBlockFace(direction);
if (face == null || amount <= 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_INVALID);
return;
}
if ((face == Direction.UP || face == Direction.DOWN) && !claim.cuboid) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_INVALID);
return;
}
if (face == Direction.EAST) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX() - amount, greater.getY(), greater.getZ());
} else if (face == Direction.WEST) {
point1 = new Vector3i(lesser.getX() + amount, lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ());
} else if (face == Direction.NORTH) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ() + amount);
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ());
} else if (face == Direction.SOUTH) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ() - amount);
}
} else {
point1 = new Vector3i(
lesser.getX() + amount,
lesser.getY(),
lesser.getZ() + amount);
point2 = new Vector3i(
greater.getX() - amount,
greater.getY(),
greater.getZ() - amount);
}
final ClaimResult result = claim.resize(point1, point2);
if (!result.successful()) {
if (result.getResultType() == ClaimResultType.OVERLAPPING_CLAIM) {
GDClaim overlapClaim = (GDClaim) result.getClaim().get();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().RESIZE_OVERLAP);
Set<Claim> claims = new HashSet<>();
claims.add(overlapClaim);
CommandHelper.showOverlapClaims(player, claims, player.getProperty(EyeLocationProperty.class).get().getValue().getFloorY());
} else {
// TODO add to lang
GriefDefenderPlugin.sendMessage(player, TextComponent.of("Could not resize claim. Reason : " + result.getResultType()).color(TextColor.RED));
}
} else {
int claimBlocksRemaining = playerData.getRemainingClaimBlocks();;
if (!claim.isAdminClaim()) {
UUID ownerID = claim.getOwnerUniqueId();
if (claim.parent != null) {
ownerID = claim.parent.getOwnerUniqueId();
}
if (ownerID.equals(player.getUniqueId())) {
claimBlocksRemaining = playerData.getRemainingClaimBlocks();
} else {
GDPlayerData ownerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), ownerID);
claimBlocksRemaining = ownerData.getRemainingClaimBlocks();
final Player owner = Sponge.getServer().getPlayer(ownerID).orElse(null);
if (owner == null || !owner.isOnline()) {
GriefDefenderPlugin.getInstance().dataStore.clearCachedPlayerData(player.getWorld().getUniqueId(), ownerID);
}
}
}
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(player.getUniqueId()).orElse(null);
if (playerAccount != null) {
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final BigDecimal currentFunds = playerAccount.getBalance(defaultCurrency);
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final double claimableChunks = claimBlocksRemaining / 65536.0;
final Map<String, Object> params = ImmutableMap.of(
"balance", String.valueOf("$" + currentFunds.intValue()),
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_3D, params));
} else {
final Map<String, Object> params = ImmutableMap.of(
"balance", String.valueOf("$" + currentFunds.intValue()),
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_2D, params));
}
}
} else {
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final double claimableChunks = claimBlocksRemaining / 65536.0;
final Map<String, Object> params = ImmutableMap.of(
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.RESIZE_SUCCESS_3D, params));
} else {
final Map<String, Object> params = ImmutableMap.of(
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.RESIZE_SUCCESS_2D, params));
}
}
playerData.revertActiveVisual(player);
claim.getVisualizer().resetVisuals();
claim.getVisualizer().createClaimBlockVisuals(player.getProperty(EyeLocationProperty.class).get().getValue().getFloorY(), player.getLocation(), playerData);
claim.getVisualizer().apply(player);
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() != null) {
GriefDefenderPlugin.getInstance().getWorldEditProvider().visualizeClaim(claim, player, playerData, false);
}
}
}
}

View File

@ -0,0 +1,146 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import java.util.HashSet;
import java.util.Set;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.visual.ClaimVisual;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.ClaimTypeRegistryModule;
import com.griefdefender.util.EconomyUtil;
import com.griefdefender.util.PlayerUtil;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.CLAIM_CREATE)
public class CommandClaimCreate extends BaseCommand {
@CommandCompletion("@gddummy @gdclaimtypes @gddummy")
@CommandAlias("claimcreate")
@Description("Creates a claim around the player.")
@Syntax("<radius> [type] [player]")
@Subcommand("claim create")
public void execute(Player player, int radius, @Optional String type) {
final Location<World> location = player.getLocation();
final World world = location.getExtent();
final int minClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.MIN_LEVEL);
final int maxClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.MAX_LEVEL);
if (location.getBlockY() < minClaimLevel || location.getBlockY() > maxClaimLevel) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_CHEST_OUTSIDE_LEVEL,
ImmutableMap.of(
"min-level", minClaimLevel,
"max-level", maxClaimLevel));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final Vector3i lesserBoundary = new Vector3i(
location.getBlockX() - radius,
minClaimLevel,
location.getBlockZ() - radius);
final Vector3i greaterBoundary = new Vector3i(
location.getBlockX() + radius,
maxClaimLevel,
location.getBlockZ() + radius);
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPlayerData playerData = user.getInternalPlayerData();
final ClaimType claimType = ClaimTypeRegistryModule.getInstance().getById(type).orElse(ClaimTypes.BASIC);
final boolean cuboid = playerData.getClaimCreateMode() == CreateModeTypes.VOLUME;
if ((claimType == ClaimTypes.BASIC || claimType == ClaimTypes.TOWN) && GriefDefenderPlugin.getGlobalConfig().getConfig().economy.economyMode) {
EconomyUtil.getInstance().economyCreateClaimConfirmation(player, playerData, location.getBlockY(), lesserBoundary, greaterBoundary, claimType,
cuboid, playerData.claimSubdividing);
return;
}
final ClaimResult result = GriefDefender.getRegistry().createBuilder(Claim.Builder.class)
.bounds(lesserBoundary, greaterBoundary)
.cuboid(cuboid)
.owner(user.getUniqueId())
.type(claimType)
.world(world.getUniqueId())
.build();
GDClaim gdClaim = (GDClaim) result.getClaim().orElse(null);
if (!result.successful()) {
if (result.getResultType() == ClaimResultType.OVERLAPPING_CLAIM) {
GDClaim overlapClaim = (GDClaim) result.getClaim().get();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CREATE_OVERLAP_SHORT);
Set<Claim> claims = new HashSet<>();
claims.add(overlapClaim);
CommandHelper.showOverlapClaims(player, claims, location.getBlockY());
} else if (result.getResultType() == ClaimResultType.CLAIM_EVENT_CANCELLED) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CREATE_CANCEL);
} else {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CREATE_FAILED_RESULT,
ImmutableMap.of("reason", result.getResultType())));
}
return;
} else {
playerData.lastShovelLocation = null;
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CREATE_SUCCESS,
ImmutableMap.of(
"type", gdClaim.getFriendlyNameType(true)));
GriefDefenderPlugin.sendMessage(player, message);
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() != null) {
GriefDefenderPlugin.getInstance().getWorldEditProvider().stopVisualDrag(player);
GriefDefenderPlugin.getInstance().getWorldEditProvider().visualizeClaim(gdClaim, player, playerData, false);
}
gdClaim.getVisualizer().createClaimBlockVisuals(location.getBlockY(), player.getLocation(), playerData);
gdClaim.getVisualizer().apply(player, false);
}
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CUBOID_CLAIMS)
public class CommandClaimCuboid extends BaseCommand {
@CommandAlias("cuboid")
@Description("Toggles cuboid claims mode.")
@Subcommand("cuboid")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (playerData.getClaimCreateMode() == CreateModeTypes.AREA) {
playerData.setClaimCreateMode(CreateModeTypes.VOLUME);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CUBOID_ENABLED);
} else {
playerData.setClaimCreateMode(CreateModeTypes.AREA);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CUBOID_DISABLED);
}
}
}

View File

@ -0,0 +1,121 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_DELETE_CLAIMS)
public class CommandClaimDelete extends BaseCommand {
protected boolean deleteTopLevelClaim = false;
@CommandAlias("deleteclaim")
@Description("Deletes the claim you're standing in, even if it's not your claim.")
@Subcommand("delete claim")
public void execute(Player player) {
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_FOUND);
return;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_DELETE,
ImmutableMap.of(
"type", claim.getType().getName()));
if (claim.isAdminClaim() && !player.hasPermission(GDPermissions.DELETE_CLAIM_ADMIN)) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
if (claim.isBasicClaim() && !player.hasPermission(GDPermissions.DELETE_CLAIM_BASIC)) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final Component confirmationText = TextComponent.builder()
.append(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_CLAIM_WARNING,
ImmutableMap.of("player", claim.getOwnerName().color(TextColor.AQUA))))
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(player, claim, deleteTopLevelClaim))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(player, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player player, Claim claim, boolean deleteTopLevelClaim) {
return confirm -> {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDCauseStackManager.getInstance().pushCause(player);
ClaimResult claimResult = GriefDefenderPlugin.getInstance().dataStore.deleteClaim(claim, !deleteTopLevelClaim);
GDCauseStackManager.getInstance().popCause();
if (!claimResult.successful()) {
GriefDefenderPlugin.sendMessage(player, claimResult.getMessage().orElse(MessageCache.getInstance().PLUGIN_EVENT_CANCEL));
return;
}
PermissionUtil.getInstance().clearPermissions((GDClaim) claim);
playerData.revertActiveVisual(player);
if (claim.isTown()) {
playerData.inTown = false;
playerData.townChat = false;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_CLAIM_SUCCESS,
ImmutableMap.of("player", claim.getOwnerName().color(TextColor.AQUA)));
GriefDefenderPlugin.sendMessage(player, message);
};
}
}

View File

@ -0,0 +1,110 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_DELETE_CLAIMS)
public class CommandClaimDeleteAll extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("deleteall")
@Description("Delete all of another player's claims.")
@Syntax("<player>")
@Subcommand("delete all")
public void execute(Player src, User otherPlayer) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(src.getWorld(), otherPlayer.getUniqueId());
int originalClaimCount = playerData.getInternalClaims().size();
if (originalClaimCount == 0) {
TextAdapter.sendComponent(src, TextComponent.of("Player " + otherPlayer.getName() + " has no claims to delete.", TextColor.RED));
return;
}
final Component confirmationText = TextComponent.builder("")
.append(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_PLAYER_WARNING,
ImmutableMap.of("player", TextComponent.of(otherPlayer.getName()).color(TextColor.AQUA))))
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(src, otherPlayer, playerData))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(src, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player src, User otherPlayer, GDPlayerData playerData) {
return confirm -> {
GDCauseStackManager.getInstance().pushCause(src);
GDRemoveClaimEvent event = new GDRemoveClaimEvent(ImmutableList.copyOf(playerData.getInternalClaims()));
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
GriefDefenderPlugin.sendMessage(src, event.getMessage().orElse(MessageCache.getInstance().PLUGIN_EVENT_CANCEL));
return;
}
GriefDefenderPlugin.getInstance().dataStore.deleteClaimsForPlayer(otherPlayer.getUniqueId());
if (src != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_PLAYER_SUCCESS, ImmutableMap.of(
"player", TextComponent.of(otherPlayer.getName()).color(TextColor.AQUA)));
GriefDefenderPlugin.sendMessage(src, message);
// revert any current visualization
playerData.revertActiveVisual(src);
}
};
}
}

View File

@ -0,0 +1,90 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_DELETE_ADMIN_CLAIMS)
public class CommandClaimDeleteAllAdmin extends BaseCommand {
@CommandAlias("deletealladmin")
@Description("Deletes all administrative claims.")
@Subcommand("delete alladmin")
public void execute(Player player) {
final Component confirmationText = TextComponent.builder("")
.append(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_TYPE_WARNING,
ImmutableMap.of("type", TextComponent.of("ADMIN").color(TextColor.RED))))
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(player))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(player, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player player) {
return confirm -> {
ClaimResult claimResult = GriefDefenderPlugin.getInstance().dataStore.deleteAllAdminClaims(player, player.getWorld());
if (!claimResult.successful()) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_TYPE_NOT_FOUND,
ImmutableMap.of(
"type", ClaimTypes.ADMIN.getName().toLowerCase()));
GriefDefenderPlugin.sendMessage(player, claimResult.getMessage().orElse(message));
return;
}
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_TYPE_SUCCESS,
ImmutableMap.of("type", TextComponent.of("ADMIN").color(TextColor.RED))));
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.revertActiveVisual(player);
};
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_DELETE_CLAIMS)
public class CommandClaimDeleteTop extends CommandClaimDelete {
public CommandClaimDeleteTop() {
this.deleteTopLevelClaim = true;
}
@CommandAlias("deletetop")
@Description("Deletes the claim you're standing in, even if it's not your claim.")
@Subcommand("delete top")
public void execute(Player player) {
super.execute(player);
}
}

View File

@ -0,0 +1,201 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.util.Direction;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PlayerUtil;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_EXPAND)
public class CommandClaimExpand extends BaseCommand {
@CommandCompletion("@gddummy @gdDirections @gddummy")
@CommandAlias("claimexpand|expandclaim")
@Description("Expands the claim in the direction you are facing.")
@Syntax("<amount> [direction]")
@Subcommand("claim expand")
public void execute(Player player, int amount, @Optional String direction) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(user.getInternalPlayerData(), player.getLocation());
final GDPlayerData playerData = user.getInternalPlayerData();
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
if (!claim.getInternalClaimData().isResizable() || (!claim.getOwnerUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_RESIZE);
return;
}
final Vector3i lesser = claim.lesserBoundaryCorner;
final Vector3i greater = claim.greaterBoundaryCorner;
Vector3i point1 = null;
Vector3i point2 = null;
if (direction == null || !direction.equalsIgnoreCase("all")) {
final Direction face = direction == null ? PlayerUtil.getInstance().getBlockFace(player) : PlayerUtil.getInstance().getBlockFace(direction);
if (face == null || amount <= 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_INVALID);
return;
}
if ((face == Direction.UP || face == Direction.DOWN) && !claim.cuboid) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_INVALID);
return;
}
if (face == Direction.EAST) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX() + amount, greater.getY(), greater.getZ());
} else if (face == Direction.WEST) {
point1 = new Vector3i(lesser.getX() - amount, lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ());
} else if (face == Direction.NORTH) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ() - amount);
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ());
} else if (face == Direction.SOUTH) {
point1 = new Vector3i(lesser.getX(), lesser.getY(), lesser.getZ());
point2 = new Vector3i(greater.getX(), greater.getY(), greater.getZ() + amount);
}
} else {
point1 = new Vector3i(
lesser.getX() - amount,
lesser.getY(),
lesser.getZ() - amount);
point2 = new Vector3i(
greater.getX() + amount,
greater.getY(),
greater.getZ() + amount);
}
final ClaimResult result = claim.resize(point1, point2);
if (!result.successful()) {
if (result.getResultType() == ClaimResultType.OVERLAPPING_CLAIM) {
GDClaim overlapClaim = (GDClaim) result.getClaim().get();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().RESIZE_OVERLAP);
Set<Claim> claims = new HashSet<>();
claims.add(overlapClaim);
CommandHelper.showOverlapClaims(player, claims, player.getProperty(EyeLocationProperty.class).get().getValue().getFloorY());
} else {
// TODO add to lang
GriefDefenderPlugin.sendMessage(player, TextComponent.of("Could not resize claim. Reason : " + result.getResultType()).color(TextColor.RED));
}
} else {
int claimBlocksRemaining = playerData.getRemainingClaimBlocks();;
if (!claim.isAdminClaim()) {
UUID ownerID = claim.getOwnerUniqueId();
if (claim.parent != null) {
ownerID = claim.parent.getOwnerUniqueId();
}
if (ownerID.equals(player.getUniqueId())) {
claimBlocksRemaining = playerData.getRemainingClaimBlocks();
} else {
GDPlayerData ownerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), ownerID);
claimBlocksRemaining = ownerData.getRemainingClaimBlocks();
final Player owner = Sponge.getServer().getPlayer(ownerID).orElse(null);
if (owner == null || !owner.isOnline()) {
GriefDefenderPlugin.getInstance().dataStore.clearCachedPlayerData(player.getWorld().getUniqueId(), ownerID);
}
}
}
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(player.getUniqueId()).orElse(null);
if (playerAccount != null) {
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final BigDecimal currentFunds = playerAccount.getBalance(defaultCurrency);
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final double claimableChunks = claimBlocksRemaining / 65536.0;
final Map<String, Object> params = ImmutableMap.of(
"balance", String.valueOf("$" + currentFunds.intValue()),
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_3D, params));
} else {
final Map<String, Object> params = ImmutableMap.of(
"balance", String.valueOf("$" + currentFunds.intValue()),
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_2D, params));
}
}
} else {
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final double claimableChunks = claimBlocksRemaining / 65536.0;
final Map<String, Object> params = ImmutableMap.of(
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.RESIZE_SUCCESS_3D, params));
} else {
final Map<String, Object> params = ImmutableMap.of(
"block-amount", claimBlocksRemaining);
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.RESIZE_SUCCESS_2D, params));
}
}
playerData.revertActiveVisual(player);
claim.getVisualizer().resetVisuals();
claim.getVisualizer().createClaimBlockVisuals(player.getProperty(EyeLocationProperty.class).get().getValue().getFloorY(), player.getLocation(), playerData);
claim.getVisualizer().apply(player);
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() != null) {
GriefDefenderPlugin.getInstance().getWorldEditProvider().visualizeClaim(claim, player, playerData, false);
}
}
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_CLAIM_FAREWELL)
public class CommandClaimFarewell extends BaseCommand {
@CommandAlias("claimfarewell")
@Description("Sets the farewell message of your claim.")
@Syntax("<message>")
@Subcommand("claim farewell")
public void execute(Player player, String message) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (claim.allowEdit(player) != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_EDIT_CLAIM);
return;
}
TextComponent farewell = LegacyComponentSerializer.legacy().deserialize(message, '&');
if (farewell == TextComponent.empty() || farewell.content().equals("clear")) {
claim.getInternalClaimData().setFarewell(null);
} else {
claim.getInternalClaimData().setFarewell(farewell);
}
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
Component resultMessage = null;
if (!claim.getInternalClaimData().getFarewell().isPresent()) {
resultMessage = MessageCache.getInstance().CLAIM_FAREWELL_CLEAR;
} else {
resultMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_FAREWELL,
ImmutableMap.of(
"farewell", farewell));
}
TextAdapter.sendComponent(player, resultMessage);
}
}

View File

@ -0,0 +1,57 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_FLAGS_CLAIM)
public class CommandClaimFlag extends ClaimFlagBase {
public CommandClaimFlag() {
super(ClaimSubjectType.GLOBAL);
}
@CommandCompletion("@gdflags @gdmcids @gdtristates @gdcontexts @gddummy")
@CommandAlias("cf|claimflag")
@Description("Gets/Sets claim flags in the claim you are standing in.")
@Syntax("<flag> <target> <value> [context[key=value]]")
@Subcommand("flag claim")
public void execute(Player player, @Optional String[] args) throws InvalidCommandArgument {
this.subject = GriefDefenderPlugin.DEFAULT_HOLDER;
this.friendlySubjectName = "ALL";
super.execute(player, args);
}
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_FLAGS_DEBUG)
public class CommandClaimFlagDebug extends BaseCommand {
@CommandAlias("cfd")
@Description("Toggles claim flag debug mode.")
@Subcommand("claim debug")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final Component result = claim.allowEdit(user, true);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
playerData.debugClaimPermissions = !playerData.debugClaimPermissions;
if (!playerData.debugClaimPermissions) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CLAIMFLAGDEBUG_DISABLED);
} else {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CLAIMFLAGDEBUG_ENABLED);
}
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_FLAGS_GROUP)
public class CommandClaimFlagGroup extends ClaimFlagBase {
public CommandClaimFlagGroup() {
super(ClaimSubjectType.GROUP);
}
@CommandCompletion("@gdgroups @gdflags @gdmcids @gdtristates @gdcontexts @gddummy")
@CommandAlias("cfg")
@Description("Gets/Sets flag permission for a group in claim you are standing in.")
@Syntax("<group> <flag> <target> <value> [context[key=value]]")
@Subcommand("flag group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument {
if (args.length < 2 || args.length > 3) {
throw new InvalidCommandArgument();
}
if (!PermissionUtil.getInstance().hasGroupSubject(group)) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_INVALID_GROUP, ImmutableMap.of(
"group", group));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
/*String reason = ctx.<String>getOne("reason").orElse(null);
Text reasonText = null;
if (reason != null) {
reasonText = TextSerializers.FORMATTING_CODE.deserialize(reason);
}*/
this.subject = PermissionHolderCache.getInstance().getOrCreateHolder(group);
this.friendlySubjectName = group;
super.execute(player, args);
}
}

View File

@ -0,0 +1,66 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_FLAGS_PLAYER)
public class CommandClaimFlagPlayer extends ClaimFlagBase {
public CommandClaimFlagPlayer() {
super(ClaimSubjectType.PLAYER);
}
@CommandCompletion("@gdplayers @gdflags @gdmcids @gdtristates @gdcontexts @gddummy")
@CommandAlias("cfp")
@Description("Gets/Sets flag permission for a player in claim you are standing in.")
@Syntax("<player> <flag> <target> <value> [context[key=value]]")
@Subcommand("flag player")
public void execute(Player player, User user, @Optional String[] args) throws InvalidCommandArgument {
this.subject = PermissionHolderCache.getInstance().getOrCreateUser(user);
this.friendlySubjectName = user.getName();
if (user.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS) && !player.hasPermission(GDPermissions.SET_ADMIN_FLAGS)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_PLAYER_ADMIN_FLAGS);
return;
}
super.execute(player, args);
}
}

View File

@ -0,0 +1,102 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.context.Context;
import java.util.Set;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_FLAGS_RESET)
public class CommandClaimFlagReset extends BaseCommand {
@CommandAlias("cfr")
@Description("Resets a claim to flag defaults.")
@Subcommand("flag reset")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_RESET_FLAGS,
ImmutableMap.of(
"type", claim.getType().getName()));
if (claim.isWilderness()) {
if (!player.hasPermission(GDPermissions.MANAGE_WILDERNESS)) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
} else if (claim.isAdminClaim()) {
if (!player.getUniqueId().equals(claim.getOwnerUniqueId()) && !player.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS)) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
} else if (!player.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS) && (claim.isBasicClaim() || claim.isSubdivision()) && !player.getUniqueId().equals(claim.getOwnerUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_RESET_FLAGS_SELF);
return;
}
final Component confirmationText = TextComponent.builder()
.append(MessageCache.getInstance().FLAG_RESET_WARNING)
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(player, claim))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(player, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player player, Claim claim) {
return confirm -> {
// Remove persisted data
PermissionUtil.getInstance().clearPermissions((GDClaim) claim);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().FLAG_RESET_SUCCESS);
};
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_CLAIM_GREETING)
public class CommandClaimGreeting extends BaseCommand {
@CommandAlias("claimgreeting")
@Description("Sets the greeting message of your claim.")
@Syntax("<message>")
@Subcommand("claim greeting")
public void execute(Player player, String message) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component result = claim.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
final TextComponent greeting = LegacyComponentSerializer.legacy().deserialize(message, '&');
if (greeting == TextComponent.empty() || greeting.content().equals("clear")) {
claim.getInternalClaimData().setGreeting(null);
} else {
claim.getInternalClaimData().setGreeting(greeting);
}
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
Component resultMessage = null;
if (!claim.getInternalClaimData().getGreeting().isPresent()) {
resultMessage = MessageCache.getInstance().CLAIM_GREETING_CLEAR;
} else {
resultMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_GREETING,
ImmutableMap.of(
"greeting", greeting));
}
TextAdapter.sendComponent(player, resultMessage);
}
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_IGNORE_CLAIMS)
public class CommandClaimIgnore extends BaseCommand {
@CommandAlias("claimignore|ignoreclaims|ic")
@Description("Toggles ignore claims mode.")
@Subcommand("claim ignore")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (claim.isBasicClaim() && !playerData.ignoreBasicClaims || claim.isWilderness() && !playerData.ignoreWilderness || claim.isAdminClaim() && !playerData.ignoreAdminClaims) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_IGNORE, ImmutableMap.of(
"type", claim.getType().getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
playerData.ignoreClaims = !playerData.ignoreClaims;
if (!playerData.ignoreClaims) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_RESPECTING);
} else {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_IGNORE);
}
}
}

View File

@ -0,0 +1,888 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PlayerUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_INFO_BASE)
public class CommandClaimInfo extends BaseCommand {
private final Component NONE = TextComponent.of("none", TextColor.GRAY);
private final int ADMIN_SETTINGS = 0;
private final int CLAIM_EXPIRATION = 1;
private final int DENY_MESSAGES = 2;
private final int FLAG_OVERRIDES = 3;
private final int INHERIT_PARENT = 4;
private final int PVP_OVERRIDE = 5;
private final int RAID_OVERRIDE = 6;
private final int RESIZABLE = 7;
private final int REQUIRES_CLAIM_BLOCKS = 8;
private final int SIZE_RESTRICTIONS = 9;
private final int FOR_SALE = 10;
private boolean useTownInfo = false;
public CommandClaimInfo() {
}
public CommandClaimInfo(boolean useTownInfo) {
this.useTownInfo = useTownInfo;
}
@CommandAlias("claiminfo")
@Syntax("[claim_uuid]")
@Subcommand("claim info")
public void execute(CommandSource src, String[] args) {
String claimIdentifier = null;
if (args.length > 0) {
claimIdentifier = args[0];
}
Player player = null;
if (src instanceof Player) {
player = (Player) src;
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(player.getWorld().getUniqueId())) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
}
if (player == null && claimIdentifier == null) {
TextAdapter.sendComponent(src, MessageCache.getInstance().COMMAND_CLAIMINFO_NOT_FOUND);
return;
}
boolean isAdmin = src.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS);
final GDPlayerData playerData = player != null ? GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()) : null;
Claim claim = null;
if (claimIdentifier == null) {
if (player != null) {
claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
} else {
TextAdapter.sendComponent(src, MessageCache.getInstance().COMMAND_CLAIMINFO_UUID_REQUIRED);
return;
}
} else {
for (World world : Sponge.getServer().getWorlds()) {
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) {
continue;
}
final GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(world.getUniqueId());
UUID uuid = null;
try {
uuid = UUID.fromString(claimIdentifier);
claim = claimManager.getClaimByUUID(uuid).orElse(null);
if (claim != null) {
break;
}
} catch (IllegalArgumentException e) {
}
if (uuid == null) {
final List<Claim> claimList = claimManager.getClaimsByName(claimIdentifier);
if (!claimList.isEmpty()) {
claim = claimList.get(0);
}
}
}
}
if (claim == null) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().CLAIM_NOT_FOUND);
return;
}
if (this.useTownInfo) {
if (!claim.isInTown()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_NOT_IN);
return;
}
claim = claim.getTown().get();
}
final GDClaim gdClaim = (GDClaim) claim;
final GDPermissionUser owner = PermissionHolderCache.getInstance().getOrCreateUser(claim.getOwnerUniqueId());
final UUID ownerUniqueId = claim.getOwnerUniqueId();
if (!isAdmin) {
isAdmin = playerData.canIgnoreClaim(gdClaim);
}
// if not owner of claim, validate perms
if (!isAdmin && !player.getUniqueId().equals(claim.getOwnerUniqueId())) {
if (!gdClaim.getInternalClaimData().getContainers().contains(player.getUniqueId())
&& !gdClaim.getInternalClaimData().getBuilders().contains(player.getUniqueId())
&& !gdClaim.getInternalClaimData().getManagers().contains(player.getUniqueId())
&& !player.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS)) {
TextAdapter.sendComponent(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
}
final Component allowEdit = gdClaim.allowEdit(player);
List<Component> textList = new ArrayList<>();
Component name = claim.getName().orElse(null);
Component greeting = claim.getData().getGreeting().orElse(null);
Component farewell = claim.getData().getFarewell().orElse(null);
String accessors = "";
String builders = "";
String containers = "";
String managers = "";
String accessorGroups = "";
String builderGroups = "";
String containerGroups = "";
String managerGroups = "";
final int minClaimLevel = gdClaim.getOwnerMinClaimLevel();
double claimY = gdClaim.getOwnerPlayerData() == null ? 65.0D : (minClaimLevel > 65.0D ? minClaimLevel : 65);
if (gdClaim.isCuboid()) {
claimY = gdClaim.lesserBoundaryCorner.getY();
}
Location<World> southWest = new Location<>(gdClaim.getWorld(), gdClaim.lesserBoundaryCorner.getX(), claimY, gdClaim.greaterBoundaryCorner.getZ());
Location<World> northWest = new Location<>(gdClaim.getWorld(), gdClaim.lesserBoundaryCorner.getX(), claimY, gdClaim.lesserBoundaryCorner.getZ());
Location<World> southEast = new Location<>(gdClaim.getWorld(), gdClaim.greaterBoundaryCorner.getX(), claimY, gdClaim.greaterBoundaryCorner.getZ());
Location<World> northEast = new Location<>(gdClaim.getWorld(), gdClaim.greaterBoundaryCorner.getX(), claimY, gdClaim.lesserBoundaryCorner.getZ());
// String southWestCorner =
Date created = null;
Date lastActive = null;
try {
Instant instant = claim.getData().getDateCreated();
created = Date.from(instant);
} catch(DateTimeParseException ex) {
// ignore
}
try {
Instant instant = claim.getData().getDateLastActive();
lastActive = Date.from(instant);
} catch(DateTimeParseException ex) {
// ignore
}
final int sizeX = Math.abs(claim.getGreaterBoundaryCorner().getX() - claim.getLesserBoundaryCorner().getX()) + 1;
final int sizeY = Math.abs(claim.getGreaterBoundaryCorner().getY() - claim.getLesserBoundaryCorner().getY()) + 1;
final int sizeZ = Math.abs(claim.getGreaterBoundaryCorner().getZ() - claim.getLesserBoundaryCorner().getZ()) + 1;
Component claimSize = TextComponent.empty();
if (claim.isCuboid()) {
claimSize = TextComponent.builder(" ")
.append(MessageCache.getInstance().LABEL_AREA.color(TextColor.YELLOW))
.append(": ", TextColor.YELLOW)
.append(sizeX + "x" + sizeY + "x" + sizeZ, TextColor.GRAY).build();
} else {
claimSize = TextComponent.builder(" ")
.append(MessageCache.getInstance().LABEL_AREA.color(TextColor.YELLOW))
.append(": ", TextColor.YELLOW)
.append(sizeX + "x" + sizeZ, TextColor.GRAY).build();
}
final Component claimCost = TextComponent.builder(" ")
.append(MessageCache.getInstance().LABEL_BLOCKS.color(TextColor.YELLOW))
.append(": ", TextColor.YELLOW)
.append(String.valueOf(claim.getClaimBlocks()), TextColor.GRAY).build();
if (claim.isWilderness() && name == null) {
name = TextComponent.of("Wilderness", TextColor.GREEN);
}
Component claimName = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_NAME.color(TextColor.YELLOW))
.append(" : ", TextColor.YELLOW)
.append(name == null ? NONE : name).build();
Component worldName = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_WORLD.color(TextColor.YELLOW))
.append(" : ")
.append(gdClaim.getWorld().getName(), TextColor.GRAY).build();
if (!claim.isWilderness() && !claim.isAdminClaim()) {
claimName = TextComponent.builder()
.append(claimName)
.append(" ")
.append(worldName)
.append(claimSize)
.append(claimCost).build();
}
// users
final List<UUID> accessorList = gdClaim.getUserTrustList(TrustTypes.ACCESSOR, true);
final List<UUID> builderList = gdClaim.getUserTrustList(TrustTypes.BUILDER, true);
final List<UUID> containerList = gdClaim.getUserTrustList(TrustTypes.CONTAINER, true);
final List<UUID> managerList = gdClaim.getUserTrustList(TrustTypes.MANAGER, true);
for (UUID uuid : accessorList) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
final String userName = user.getFriendlyName();
if (userName != null) {
accessors += userName + " ";
}
}
for (UUID uuid : builderList) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
final String userName = user.getFriendlyName();
if (userName != null) {
builders += userName + " ";
}
}
for (UUID uuid : containerList) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
final String userName = user.getFriendlyName();
if (userName != null) {
containers += userName + " ";
}
}
for (UUID uuid : managerList) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
final String userName = user.getFriendlyName();
if (userName != null) {
managers += userName + " ";
}
}
// groups
for (String group : gdClaim.getGroupTrustList(TrustTypes.ACCESSOR, true)) {
accessorGroups += group + " ";
}
for (String group : gdClaim.getGroupTrustList(TrustTypes.BUILDER, true)) {
builderGroups += group + " ";
}
for (String group : gdClaim.getGroupTrustList(TrustTypes.CONTAINER, true)) {
containerGroups += group + " ";
}
for (String group : gdClaim.getGroupTrustList(TrustTypes.MANAGER, true)) {
managerGroups += group + " ";
}
/*if (gpClaim.isInTown()) {
Text returnToClaimInfo = Text.builder().append(Text.of(
TextColors.WHITE, "\n[", TextColors.AQUA, "Return to standard settings", TextColors.WHITE, "]\n"))
.onClick(TextActions.executeCallback(CommandHelper.createCommandConsumer(src, "claiminfo", ""))).build();
Text townName = Text.of(TextColors.YELLOW, "Name", TextColors.WHITE, " : ", TextColors.RESET,
gpClaim.getTownClaim().getTownData().getName().orElse(NONE));
Text townTag = Text.of(TextColors.YELLOW, "Tag", TextColors.WHITE, " : ", TextColors.RESET,
gpClaim.getTownClaim().getTownData().getTownTag().orElse(NONE));
townTextList.add(returnToClaimInfo);
townTextList.add(townName);
townTextList.add(townTag);
Text townSettings = Text.builder()
.append(Text.of(TextStyles.ITALIC, TextColors.GREEN, TOWN_SETTINGS))
.onClick(TextActions.executeCallback(createSettingsConsumer(src, claim, townTextList, ClaimTypes.TOWN)))
.onHover(TextActions.showText(Text.of("Click here to view town settings")))
.build();
textList.add(townSettings);
}*/
if (isAdmin) {
Component adminSettings = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_ADMIN_SETTINGS).decoration(TextDecoration.ITALIC, true).color(TextColor.RED)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createSettingsConsumer(src, claim, generateAdminSettings(src, gdClaim), ClaimTypes.ADMIN))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_ADMIN))
.build();
textList.add(adminSettings);
}
Component bankInfo = null;
Component forSaleText = null;
if (GriefDefenderPlugin.getInstance().economyService.isPresent()) {
if (GriefDefenderPlugin.getActiveConfig(gdClaim.getWorld().getProperties()).getConfig().claim.bankTaxSystem) {
bankInfo = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_BANK_INFO.color(TextColor.GOLD).decoration(TextDecoration.ITALIC, true))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_BANK_INFO))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(Consumer -> { CommandHelper.displayClaimBankInfo(src, gdClaim, gdClaim.isTown() ? true : false, true); })))
.build();
}
forSaleText = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_FOR_SALE.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, FOR_SALE, claim.getEconomyData().isForSale() ? MessageCache.getInstance().LABEL_YES.color(TextColor.GREEN) : MessageCache.getInstance().LABEL_NO.color(TextColor.GRAY))).build();
if (claim.getEconomyData().isForSale()) {
forSaleText = TextComponent.builder()
.append(forSaleText)
.append(" ")
.append(MessageCache.getInstance().LABEL_PRICE.color(TextColor.YELLOW))
.append(" : ")
.append(String.valueOf(claim.getEconomyData().getSalePrice()), TextColor.GOLD)
.build();
}
}
Component claimId = TextComponent.builder()
.append("UUID", TextColor.YELLOW)
.append(" : ")
.append(TextComponent.builder()
.append(claim.getUniqueId().toString(), TextColor.GRAY)
.insertion(claim.getUniqueId().toString()).build()).build();
final String ownerName = PlayerUtil.getInstance().getUserName(ownerUniqueId);
Component ownerLine = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_OWNER.color(TextColor.YELLOW))
.append(" : ")
.append(ownerName != null && !claim.isAdminClaim() && !claim.isWilderness() ? ownerName : "administrator", TextColor.GOLD).build();
Component adminShowText = TextComponent.empty();
Component basicShowText = TextComponent.empty();
Component subdivisionShowText = TextComponent.empty();
Component townShowText = TextComponent.empty();
Component claimType = TextComponent.empty();
final Component whiteOpenBracket = TextComponent.of("[");
final Component whiteCloseBracket = TextComponent.of("]");
Component defaultTypeText = TextComponent.builder()
.append(whiteOpenBracket)
.append(gdClaim.getFriendlyNameType(true))
.append(whiteCloseBracket).build();
if (allowEdit != null && !isAdmin) {
adminShowText = allowEdit;
basicShowText = allowEdit;
subdivisionShowText = allowEdit;
townShowText = allowEdit;
Component adminTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.ADMIN ?
defaultTypeText : TextComponent.of("ADMIN", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(adminShowText)).build();
Component basicTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.BASIC ?
defaultTypeText : TextComponent.of("BASIC", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(basicShowText)).build();
Component subTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.SUBDIVISION ?
defaultTypeText : TextComponent.of("SUBDIVISION", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(subdivisionShowText)).build();
Component townTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.TOWN ?
defaultTypeText : TextComponent.of("TOWN", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(townShowText)).build();
claimType = TextComponent.builder()
.append(claim.isCuboid() ? "3D " : "2D ", TextColor.GREEN)
.append(adminTypeText)
.append(" ")
.append(basicTypeText)
.append(" ")
.append(subTypeText)
.append(" ")
.append(townTypeText)
.build();
} else {
Component adminTypeText = defaultTypeText;
Component basicTypeText = defaultTypeText;
Component subTypeText = defaultTypeText;
Component townTypeText = defaultTypeText;
if (!claim.isAdminClaim()) {
final Component message = ((GDClaim) claim).validateClaimType(ClaimTypes.ADMIN, ownerUniqueId, playerData).getMessage().orElse(null);
adminShowText = message != null ? message : MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_CLICK_CHANGE_CLAIM,
ImmutableMap.of("type", TextComponent.of("ADMIN ", TextColor.RED)));
if (message == null) {
adminTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.ADMIN ?
defaultTypeText : TextComponent.of("ADMIN", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimTypeConsumer(src, claim, ClaimTypes.ADMIN, isAdmin))))
.hoverEvent(HoverEvent.showText(adminShowText)).build();
} else {
adminTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.ADMIN ?
defaultTypeText : TextComponent.of("ADMIN", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(adminShowText)).build();
}
}
if (!claim.isBasicClaim()) {
final Component message = ((GDClaim) claim).validateClaimType(ClaimTypes.BASIC, ownerUniqueId, playerData).getMessage().orElse(null);
basicShowText = message != null ? message : MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_CLICK_CHANGE_CLAIM,
ImmutableMap.of("type", TextComponent.of("BASIC ", TextColor.YELLOW)));
if (message == null) {
basicTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.BASIC ? defaultTypeText : TextComponent.of("BASIC", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimTypeConsumer(src, claim, ClaimTypes.BASIC, isAdmin))))
.hoverEvent(HoverEvent.showText(basicShowText)).build();
} else {
basicTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.BASIC ? defaultTypeText : TextComponent.of("BASIC", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(basicShowText)).build();
}
}
if (!claim.isSubdivision()) {
final Component message = ((GDClaim) claim).validateClaimType(ClaimTypes.SUBDIVISION, ownerUniqueId, playerData).getMessage().orElse(null);
subdivisionShowText = message != null ? message : MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_CLICK_CHANGE_CLAIM,
ImmutableMap.of("type", TextComponent.of("SUBDIVISION ", TextColor.AQUA)));
if (message == null) {
subTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.SUBDIVISION ? defaultTypeText : TextComponent.of("SUBDIVISION", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimTypeConsumer(src, claim, ClaimTypes.SUBDIVISION, isAdmin))))
.hoverEvent(HoverEvent.showText(subdivisionShowText)).build();
} else {
subTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.SUBDIVISION ? defaultTypeText : TextComponent.of("SUBDIVISION", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(subdivisionShowText)).build();
}
}
if (!claim.isTown()) {
final Component message = ((GDClaim) claim).validateClaimType(ClaimTypes.TOWN, ownerUniqueId, playerData).getMessage().orElse(null);
townShowText = message != null ? message : MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_CLICK_CHANGE_CLAIM,
ImmutableMap.of("type", TextComponent.of("TOWN ", TextColor.GREEN)));
if (message == null) {
townTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.TOWN ? defaultTypeText : TextComponent.of("TOWN", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimTypeConsumer(src, claim, ClaimTypes.TOWN, isAdmin))))
.hoverEvent(HoverEvent.showText(townShowText)).build();
} else {
townTypeText = TextComponent.builder()
.append(claim.getType() == ClaimTypes.TOWN ? defaultTypeText : TextComponent.of("TOWN", TextColor.GRAY))
.hoverEvent(HoverEvent.showText(townShowText)).build();
}
}
claimType = TextComponent.builder()
.append(claim.isCuboid() ? "3D " : "2D ", TextColor.GREEN)
.append(adminTypeText)
.append(" ")
.append(basicTypeText)
.append(" ")
.append(subTypeText)
.append(" ")
.append(townTypeText)
.build();
}
Component claimTypeInfo = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_TYPE.color(TextColor.YELLOW))
.append(" : ")
.append(claimType).build();
Component claimInherit = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_INHERIT.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, INHERIT_PARENT, claim.getData().doesInheritParent() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimExpired = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_EXPIRED.color(TextColor.YELLOW))
.append(" : ")
.append(claim.getData().isExpired() ? TextComponent.of("YES", TextColor.RED) : TextComponent.of("NO", TextColor.GRAY)).build();
Component claimFarewell = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_FAREWELL.color(TextColor.YELLOW))
.append(" : ")
.append(farewell == null ? NONE : farewell).build();
Component claimGreeting = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_GREETING.color(TextColor.YELLOW))
.append(" : ")
.append(greeting == null ? NONE : greeting).build();
Component claimDenyMessages = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_DENY_MESSAGES.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, DENY_MESSAGES, claim.getData().allowDenyMessages() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component pvpSetting = TextComponent.of("UNDEFINED", TextColor.GRAY);
if (claim.getData().getPvpOverride() == Tristate.TRUE) {
pvpSetting = TextComponent.of("ON", TextColor.GREEN);
} else if (claim.getData().getPvpOverride() == Tristate.FALSE) {
pvpSetting = TextComponent.of("OFF", TextColor.RED);
}
Component claimPvP = TextComponent.builder()
.append("PvP", TextColor.YELLOW)
.append(" : ")
.append(getClickableInfoText(src, claim, PVP_OVERRIDE, pvpSetting)).build();
/* Component claimRaid = TextComponent.builder()
.append("Raid", TextColor.YELLOW)
.append(" : ")
.append(getClickableInfoText(src, claim, RAID_OVERRIDE, GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), owner, Options.RAID, gdClaim) == true ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
*/
Component claimSpawn = null;
if (claim.getData().getSpawnPos().isPresent()) {
Vector3i spawnPos = claim.getData().getSpawnPos().get();
Location<World> spawnLoc = new Location<>(gdClaim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
claimSpawn = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_SPAWN.color(TextColor.GREEN))
.append(" : ")
.append(spawnPos.toString(), TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN))
.build();
}
Component southWestCorner = TextComponent.builder()
.append("SW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY)
.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA)))))
.build();
Component southEastCorner = TextComponent.builder()
.append("SE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY)
.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA)))))
.build();
Component southCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_SOUTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(southWestCorner)
.append(southEastCorner).build();
Component northWestCorner = TextComponent.builder()
.append("NW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY)
.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA)))))
.build();
Component northEastCorner = TextComponent.builder()
.append("NE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY)
.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA)))))
.build();
Component northCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_NORTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(northWestCorner)
.append(northEastCorner).build();
Component claimAccessors = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_ACCESSORS.color(TextColor.YELLOW))
.append(" : ")
.append(accessors.equals("") ? NONE : TextComponent.of(accessors, TextColor.BLUE))
.append(" ")
.append(accessorGroups, TextColor.LIGHT_PURPLE).build();
Component claimBuilders = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_BUILDERS.color(TextColor.YELLOW))
.append(" : ")
.append(builders.equals("") ? NONE : TextComponent.of(builders, TextColor.BLUE))
.append(" ")
.append(builderGroups, TextColor.LIGHT_PURPLE).build();
Component claimContainers = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_CONTAINERS.color(TextColor.YELLOW))
.append(" : ")
.append(containers.equals("") ? NONE : TextComponent.of(containers, TextColor.BLUE))
.append(" ")
.append(containerGroups, TextColor.LIGHT_PURPLE).build();
Component claimCoowners = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_MANAGERS.color(TextColor.YELLOW))
.append(" : ")
.append(managers.equals("") ? NONE : TextComponent.of(managers, TextColor.BLUE))
.append(" ")
.append(managerGroups, TextColor.LIGHT_PURPLE).build();
Component dateCreated = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_CREATED.color(TextColor.YELLOW))
.append(" : ")
.append(created != null ? TextComponent.of(created.toString(), TextColor.GRAY) : MessageCache.getInstance().LABEL_UNKNOWN.color(TextColor.GRAY)).build();
Component dateLastActive = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_LAST_ACTIVE.color(TextColor.YELLOW))
.append(" : ")
.append(lastActive != null ? TextComponent.of(lastActive.toString(), TextColor.GRAY) : MessageCache.getInstance().LABEL_UNKNOWN.color(TextColor.GRAY)).build();
if (claimSpawn != null) {
textList.add(claimSpawn);
}
if (bankInfo != null) {
textList.add(bankInfo);
}
textList.add(claimName);
textList.add(ownerLine);
textList.add(claimTypeInfo);
if (!claim.isAdminClaim() && !claim.isWilderness()) {
textList.add(TextComponent.builder()
.append(claimInherit)
.append(" ")
.append(claimExpired).build());
if (forSaleText != null) {
textList.add(forSaleText);
}
}
textList.add(TextComponent.builder()
.append(claimPvP)
.append(" ")
.append(claimDenyMessages)
.build());
textList.add(claimAccessors);
textList.add(claimBuilders);
textList.add(claimContainers);
textList.add(claimCoowners);
textList.add(claimGreeting);
textList.add(claimFarewell);
textList.add(dateCreated);
textList.add(dateLastActive);
textList.add(claimId);
textList.add(northCorners);
textList.add(southCorners);
if (!claim.getParent().isPresent()) {
textList.remove(claimInherit);
}
if (claim.isAdminClaim()) {
textList.remove(bankInfo);
textList.remove(dateLastActive);
}
if (claim.isWilderness()) {
textList.remove(bankInfo);
textList.remove(claimInherit);
textList.remove(claimTypeInfo);
textList.remove(dateLastActive);
textList.remove(northCorners);
textList.remove(southCorners);
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(MessageCache.getInstance().CLAIMINFO_UI_TITLE_CLAIMINFO.color(TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(textList);
paginationBuilder.sendTo(src);
}
public static Consumer<CommandSource> createSettingsConsumer(CommandSource src, Claim claim, List<Component> textList, ClaimType type) {
return settings -> {
Component name = type == ClaimTypes.TOWN ? MessageCache.getInstance().CLAIMINFO_UI_TOWN_SETTINGS : MessageCache.getInstance().CLAIMINFO_UI_ADMIN_SETTINGS;
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(name.color(TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(textList);
paginationBuilder.sendTo(src);
};
}
private List<Component> generateAdminSettings(CommandSource src, GDClaim claim) {
List<Component> textList = new ArrayList<>();
Component returnToClaimInfo = TextComponent.builder()
.append("\n[")
.append(MessageCache.getInstance().CLAIMINFO_UI_RETURN_SETTINGS.color(TextColor.AQUA))
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createCommandConsumer(src, "claiminfo", claim.getUniqueId().toString())))).build();
Component claimResizable = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_RESIZABLE.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, RESIZABLE, claim.getInternalClaimData().isResizable() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimRequiresClaimBlocks = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_REQUIRES_CLAIM_BLOCKS.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, REQUIRES_CLAIM_BLOCKS, claim.getInternalClaimData().requiresClaimBlocks() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimSizeRestrictions = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_SIZE_RESTRICTIONS.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, SIZE_RESTRICTIONS, claim.getInternalClaimData().hasSizeRestrictions() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimExpiration = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_CLAIM_EXPIRATION.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, CLAIM_EXPIRATION, claim.getInternalClaimData().allowExpiration() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimFlagOverrides = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_FLAG_OVERRIDES.color(TextColor.YELLOW))
.append(" : ")
.append(getClickableInfoText(src, claim, FLAG_OVERRIDES, claim.getInternalClaimData().allowFlagOverrides() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
textList.add(returnToClaimInfo);
if (!claim.isAdminClaim() && !claim.isWilderness()) {
textList.add(claimRequiresClaimBlocks);
textList.add(claimExpiration);
textList.add(claimResizable);
textList.add(claimSizeRestrictions);
}
textList.add(claimFlagOverrides);
int fillSize = 20 - (textList.size() + 4);
for (int i = 0; i < fillSize; i++) {
textList.add(TextComponent.of(" "));
}
return textList;
}
private void executeAdminSettings(CommandSource src, GDClaim claim) {
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(MessageCache.getInstance().CLAIMINFO_UI_ADMIN_SETTINGS).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(generateAdminSettings(src, claim));
paginationBuilder.sendTo(src);
}
public Component getClickableInfoText(CommandSource src, Claim claim, int titleId, Component infoText) {
Component onClickText = MessageCache.getInstance().CLAIMINFO_UI_CLICK_TOGGLE;
boolean hasPermission = true;
if (src instanceof Player) {
Component denyReason = ((GDClaim) claim).allowEdit((Player) src);
if (denyReason != null) {
onClickText = denyReason;
hasPermission = false;
}
}
TextComponent.Builder textBuilder = TextComponent.builder()
.append(infoText)
.hoverEvent(HoverEvent.showText(onClickText));
if (hasPermission) {
textBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimInfoConsumer(src, claim, titleId))));
}
return textBuilder.build();
}
private Consumer<CommandSource> createClaimInfoConsumer(CommandSource src, Claim claim, int titleId) {
GDClaim gpClaim = (GDClaim) claim;
return info -> {
switch (titleId) {
case INHERIT_PARENT :
if (!claim.getParent().isPresent() || !src.hasPermission(GDPermissions.COMMAND_CLAIM_INHERIT)) {
return;
}
gpClaim.getInternalClaimData().setInheritParent(!gpClaim.getInternalClaimData().doesInheritParent());
gpClaim.getInternalClaimData().setRequiresSave(true);
claim.getData().save();
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
return;
case CLAIM_EXPIRATION :
gpClaim.getInternalClaimData().setExpiration(!gpClaim.getInternalClaimData().allowExpiration());
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
break;
case DENY_MESSAGES :
gpClaim.getInternalClaimData().setDenyMessages(!gpClaim.getInternalClaimData().allowDenyMessages());
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
return;
case FLAG_OVERRIDES :
gpClaim.getInternalClaimData().setFlagOverrides(!gpClaim.getInternalClaimData().allowFlagOverrides());
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
break;
case PVP_OVERRIDE :
Tristate value = gpClaim.getInternalClaimData().getPvpOverride();
if (value == Tristate.UNDEFINED) {
gpClaim.getInternalClaimData().setPvpOverride(Tristate.TRUE);
} else if (value == Tristate.TRUE) {
gpClaim.getInternalClaimData().setPvpOverride(Tristate.FALSE);
} else {
gpClaim.getInternalClaimData().setPvpOverride(Tristate.UNDEFINED);
}
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
return;
/*case RAID_OVERRIDE :
GDPermissionHolder holder = null;
final GDPlayerData playerData = ((GDClaim) claim).getOwnerPlayerData();
if (playerData == null) {
holder = GriefDefenderPlugin.DEFAULT_HOLDER;
} else {
holder = playerData.getSubject();
}
final Boolean result = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), holder, Options.RAID, gpClaim);
final Set<Context> contexts = new HashSet<>();
contexts.add(claim.getContext());
if (result) {
PermissionUtil.getInstance().setOptionValue(holder, Options.RAID.getPermission(), "false", contexts);
} else {
PermissionUtil.getInstance().setOptionValue(holder, Options.RAID.getPermission(), "true", contexts);
}
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
return;*/
case RESIZABLE :
boolean resizable = gpClaim.getInternalClaimData().isResizable();
gpClaim.getInternalClaimData().setResizable(!resizable);
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
break;
case REQUIRES_CLAIM_BLOCKS :
boolean requiresClaimBlocks = gpClaim.getInternalClaimData().requiresClaimBlocks();
gpClaim.getInternalClaimData().setRequiresClaimBlocks(!requiresClaimBlocks);
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
break;
case SIZE_RESTRICTIONS :
boolean sizeRestrictions = gpClaim.getInternalClaimData().hasSizeRestrictions();
gpClaim.getInternalClaimData().setSizeRestrictions(!sizeRestrictions);
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
break;
case FOR_SALE :
boolean forSale = gpClaim.getEconomyData().isForSale();
gpClaim.getEconomyData().setForSale(!forSale);
gpClaim.getInternalClaimData().setRequiresSave(true);
gpClaim.getClaimStorage().save();
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
return;
default:
}
executeAdminSettings(src, gpClaim);
};
}
private static Consumer<CommandSource> createClaimTypeConsumer(CommandSource src, Claim gpClaim, ClaimType clicked, boolean isAdmin) {
GDClaim claim = (GDClaim) gpClaim;
return type -> {
if (!(src instanceof Player)) {
// ignore
return;
}
final Player player = (Player) src;
if (!isAdmin && ((GDClaim) gpClaim).allowEdit(player) != null) {
TextAdapter.sendComponent(src, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
final ClaimResult result = claim.changeType(clicked, Optional.of(player.getUniqueId()), src);
if (result.successful()) {
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
} else {
TextAdapter.sendComponent(src, result.getMessage().get());
}
};
}
}

View File

@ -0,0 +1,69 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_INHERIT)
public class CommandClaimInherit extends BaseCommand {
@CommandAlias("claiminherit")
@Description("Toggles subdivision inherit mode.")
@Subcommand("claim inherit")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component result = claim.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
if (claim.parent == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_INHERIT_ONLY_CHILD);
return;
}
claim.getData().setInheritParent(!claim.getData().doesInheritParent());
claim.getInternalClaimData().setRequiresSave(true);
if (!claim.getData().doesInheritParent()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CLAIMINHERIT_DISABLED);
} else {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_CLAIMINHERIT_ENABLED);
}
}
}

View File

@ -0,0 +1,246 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PaginationUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.world.World;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_LIST)
public class CommandClaimList extends BaseCommand {
private final ClaimType forcedType;
private final Cache<UUID, String> lastActiveClaimTypeMap = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
public CommandClaimList() {
this.forcedType = null;
}
public CommandClaimList(ClaimType type) {
this.forcedType = type;
}
@CommandCompletion("@gdplayers @gdworlds @gddummy")
@CommandAlias("claimlist|claimslist")
@Syntax("[<player>|<player> <world>]")
@Description("List information about a player's claim blocks and claims.")
@Subcommand("claim list")
public void execute(Player src, @Optional User targetPlayer, @Optional World world) {//String[] args) {
final GDPermissionUser user = targetPlayer == null ? PermissionHolderCache.getInstance().getOrCreateUser(src) : PermissionHolderCache.getInstance().getOrCreateUser(targetPlayer);
if (user == null) {
GriefDefenderPlugin.sendMessage(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_PLAYER,
ImmutableMap.of(
"player", targetPlayer)));
return;
}
if (world == null) {
world = src.getWorld();
}
showClaimList(src, user, this.forcedType, world.getUniqueId());
}
private void showClaimList(Player src, GDPermissionUser user, ClaimType type, UUID worldUniqueId) {
List<Component> claimsTextList = new ArrayList<>();
Set<Claim> claims = new HashSet<>();
final String worldName = worldUniqueId == null ? "" : Sponge.getServer().getWorld(worldUniqueId).get().getName();
final boolean otherUser = !src.getUniqueId().equals(user.getUniqueId());
for (World world : Sponge.getServer().getWorlds()) {
if (type != null && !world.getUniqueId().equals(worldUniqueId)) {
continue;
}
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(world.getUniqueId());
// load the target player's data
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world, user.getUniqueId());
Set<Claim> claimList = null;
if (type == null || otherUser) {
claimList = playerData.getClaims();
} else {
claimList = claimWorldManager.getWorldClaims();
}
for (Claim claim : claimList) {
if (claims.contains(claim)) {
continue;
}
if (((GDClaim) claim).allowEdit(src) != null && !claim.isUserTrusted(src.getUniqueId(), TrustTypes.ACCESSOR)) {
continue;
}
if (type == null) {
claims.add(claim);
} else {
if (claim.getType() == type) {
claims.add(claim);
} else if (type == ClaimTypes.SUBDIVISION) {
for (Claim child : claim.getChildren(true)) {
if (child.getType() == type) {
claims.add(child);
}
}
}
}
}
}
if (src instanceof Player) {
final Player player = (Player) src;
final String lastClaimType = this.lastActiveClaimTypeMap.getIfPresent(player.getUniqueId());
String currentType = type == null ? "OWN" : type.toString();
if (lastClaimType != null && !lastClaimType.equals(currentType.toString())) {
PaginationUtil.getInstance().resetActivePage(player.getUniqueId());
}
}
claimsTextList = CommandHelper.generateClaimTextListCommand(claimsTextList, claims, worldName, user, src, createClaimListConsumer(src, user, type, worldUniqueId), false);
final Component whiteOpenBracket = TextComponent.of("[");
final Component whiteCloseBracket = TextComponent.of("]");
Component ownedShowText = MessageCache.getInstance().CLAIMLIST_UI_CLICK_VIEW_CLAIMS;
Component adminShowText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("ADMIN", TextColor.RED)));
Component basicShowText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("BASIC", TextColor.YELLOW)));
Component subdivisionShowText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("SUBDIVISION", TextColor.AQUA)));
Component townShowText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", TextComponent.of("TOWN", TextColor.GREEN)));
Component ownedTypeText = TextComponent.builder("")
.append(type == null ?
TextComponent.builder("")
.append(whiteOpenBracket)
.append(otherUser ? TextComponent.of(user.getFriendlyName()).color(TextColor.GOLD) : MessageCache.getInstance().TITLE_OWN.color(TextColor.GOLD))
.append(whiteCloseBracket).build() : otherUser ? TextComponent.of(user.getFriendlyName()).color(TextColor.GRAY) : MessageCache.getInstance().TITLE_OWN.color(TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimListConsumer(src, user, null, worldUniqueId))))
.hoverEvent(HoverEvent.showText(ownedShowText)).build();
Component adminTypeText = TextComponent.builder("")
.append(type == ClaimTypes.ADMIN ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("ADMIN", TextColor.RED)
.append(whiteCloseBracket).build() : TextComponent.of("ADMIN", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimListConsumer(src, user, ClaimTypes.ADMIN, worldUniqueId))))
.hoverEvent(HoverEvent.showText(adminShowText)).build();
Component basicTypeText = TextComponent.builder("")
.append(type == ClaimTypes.BASIC ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("BASIC", TextColor.YELLOW)
.append(whiteCloseBracket).build() : TextComponent.of("BASIC", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimListConsumer(src, user, ClaimTypes.BASIC, worldUniqueId))))
.hoverEvent(HoverEvent.showText(basicShowText)).build();
Component subTypeText = TextComponent.builder("")
.append(type == ClaimTypes.SUBDIVISION ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("SUBDIVISION", TextColor.AQUA)
.append(whiteCloseBracket).build() : TextComponent.of("SUBDIVISION", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimListConsumer(src, user, ClaimTypes.SUBDIVISION, worldUniqueId))))
.hoverEvent(HoverEvent.showText(subdivisionShowText)).build();
Component townTypeText = TextComponent.builder("")
.append(type == ClaimTypes.TOWN ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("TOWN", TextColor.GREEN)
.append(whiteCloseBracket).build() : TextComponent.of("TOWN", TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createClaimListConsumer(src, user, ClaimTypes.TOWN, worldUniqueId))))
.hoverEvent(HoverEvent.showText(townShowText)).build();
Component claimListHead = TextComponent.builder("")
.append(" ")
.append(MessageCache.getInstance().LABEL_DISPLAYING.color(TextColor.AQUA))
.append(" : ", TextColor.AQUA)
.append(ownedTypeText)
.append(" ")
.append(otherUser ? TextComponent.of("") : adminTypeText)
.append(otherUser ? "" : " ")
.append(basicTypeText)
.append(" ")
.append(subTypeText)
.append(" ")
.append(townTypeText).build();
final int fillSize = 20 - (claimsTextList.size() + 2);
for (int i = 0; i < fillSize; i++) {
claimsTextList.add(TextComponent.of(" "));
}
PaginationList paginationList = PaginationList.builder()
.title(claimListHead).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(claimsTextList).build();
Integer activePage = 1;
if (src instanceof Player) {
final Player player = (Player) src;
activePage = PaginationUtil.getInstance().getActivePage(player.getUniqueId());
if (activePage == null) {
activePage = 1;
}
this.lastActiveClaimTypeMap.put(player.getUniqueId(), type == null ? "OWN" : type.toString());
}
paginationList.sendTo(src, activePage);
}
private Consumer<CommandSource> createClaimListConsumer(Player src, GDPermissionUser user, ClaimType type, UUID worldUniqueId) {
return consumer -> {
showClaimList(src, user, type, worldUniqueId);
};
}
}

View File

@ -0,0 +1,78 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_MODE)
public class CommandClaimMode extends BaseCommand {
@CommandAlias("claim|claimmode")
@Description("Toggles claim mode creation. Note: This will default to basic claim mode.")
@Subcommand("mode claim")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.claimMode = !playerData.claimMode;
playerData.claimSubdividing = null;
if (!playerData.claimMode) {
playerData.revertActiveVisual(player);
// check for any active WECUI visuals
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() != null) {
GriefDefenderPlugin.getInstance().getWorldEditProvider().revertVisuals(player, playerData, null);
}
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMMODE_DISABLED);
} else {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMMODE_ENABLED);
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PLAYER_REMAINING_BLOCKS_3D,
ImmutableMap.of(
"block-amount", playerData.getRemainingClaimBlocks(),
"chunk-amount", playerData.getRemainingChunks()));
GriefDefenderPlugin.sendMessage(player, message);
} else {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PLAYER_REMAINING_BLOCKS_2D,
ImmutableMap.of(
"block-amount", playerData.getRemainingClaimBlocks()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}
}

View File

@ -0,0 +1,74 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_CLAIM_NAME)
public class CommandClaimName extends BaseCommand {
@CommandAlias("claimname")
@Syntax("<name>")
@Description("Sets the name of your claim.")
@Subcommand("claim name")
public void execute(Player player, String name) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component result = claim.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
final Component text = LegacyComponentSerializer.legacy().deserialize(name, '&');
if (text == TextComponent.empty()) {
claim.getInternalClaimData().setName(null);
} else {
claim.getInternalClaimData().setName(text);
}
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_NAME,
ImmutableMap.of(
"name", text));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,85 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.entity.living.player.Player;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM)
public class CommandClaimOption extends ClaimOptionBase {
public CommandClaimOption() {
super(ClaimSubjectType.GLOBAL);
}
@CommandCompletion("@gdoptions @gddummy")
@CommandAlias("co|claimoption")
@Description("Gets/Sets claim options in the claim you are standing in.")
@Syntax("[<option> <value> [context[key=value]]")
@Subcommand("option claim")
public void execute(Player player, @Optional String[] args) throws InvalidCommandArgument {
this.subject = GriefDefenderPlugin.DEFAULT_HOLDER;
this.friendlySubjectName = "ALL";
super.execute(player, args);
}
}

View File

@ -0,0 +1,74 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_GROUP)
public class CommandClaimOptionGroup extends ClaimOptionBase {
public CommandClaimOptionGroup() {
super(ClaimSubjectType.GROUP);
}
@CommandCompletion("@gdgroups @gdoptions @gddummy")
@CommandAlias("cog")
@Description("Gets/Sets option for a group in claim you are standing in.")
@Syntax("<group> <option> <value> [context[key=value]]")
@Subcommand("option group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument {
if (args.length < 2 || args.length > 3) {
throw new InvalidCommandArgument();
}
if (!PermissionUtil.getInstance().hasGroupSubject(group)) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_INVALID_GROUP, ImmutableMap.of(
"group", group));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
this.subject = PermissionHolderCache.getInstance().getOrCreateHolder(group);
this.friendlySubjectName = group;
super.execute(player, args);
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_PLAYER)
public class CommandClaimOptionPlayer extends ClaimOptionBase {
public CommandClaimOptionPlayer() {
super(ClaimSubjectType.PLAYER);
}
@CommandCompletion("@gdplayers @gdoptions @gddummy")
@CommandAlias("cop")
@Description("Gets/Sets option for a player in claim you are standing in.")
@Syntax("<player> <option> <value> [context[key=value]]")
@Subcommand("option player")
public void execute(Player src, User player, @Optional String[] args) throws InvalidCommandArgument {
this.subject = PermissionHolderCache.getInstance().getOrCreateUser(player);
this.friendlySubjectName = player.getName();
super.execute(src, args);
}
}

View File

@ -0,0 +1,147 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.permission.Context;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.ui.UIHelper;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.entity.living.player.Player;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_PERMISSION_GROUP)
public class CommandClaimPermissionGroup extends BaseCommand {
@CommandCompletion("@gdgroups @gddummy")
@CommandAlias("cpg")
@Description("Sets a permission on a group with a claim context.")
@Syntax("<group> [<permission> <value>]")
@Subcommand("permission group")
public void execute(Player player, String group, @Optional String[] args) throws CommandException, InvalidCommandArgument {
String permission = null;
String value = null;
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (args.length > 0) {
if (args.length < 2) {
throw new InvalidCommandArgument();
}
permission = args[0];
if (!playerData.ignoreClaims && permission != null && !player.hasPermission(permission)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_ASSIGN_WITHOUT_HAVING);
return;
}
value = args[1];
}
if (!PermissionUtil.getInstance().hasGroupSubject(group)) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_INVALID_GROUP));
return;
}
final GDPermissionHolder subj = PermissionHolderCache.getInstance().getOrCreateHolder(group);
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE,
ImmutableMap.of(
"type", claim.getType().getName()));
if (claim.isWilderness() && !playerData.canManageWilderness) {
GriefDefenderPlugin.sendMessage(player, message);
return;
} else if (claim.isAdminClaim() && !playerData.canManageAdminClaims) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
Set<Context> contexts = new HashSet<>();
contexts.add(claim.getContext());
if (permission == null || value == null) {
List<Component> permList = Lists.newArrayList();
Map<String, Boolean> permissions = PermissionUtil.getInstance().getPermissions(subj, contexts);
for (Map.Entry<String, Boolean> permissionEntry : permissions.entrySet()) {
Boolean permValue = permissionEntry.getValue();
Component permText = TextComponent.builder("")
.append(permissionEntry.getKey(), TextColor.GREEN)
.append(" ")
.append(permValue.toString(), TextColor.GOLD).build();
permList.add(permText);
}
List<Component> finalTexts = UIHelper.stripeText(permList);
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(TextComponent.of(subj.getFriendlyName() + " Permissions", TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(finalTexts);
paginationBuilder.sendTo(player);
return;
}
Tristate tristateValue = PermissionUtil.getInstance().getTristateFromString(value);
if (tristateValue == null) {
TextAdapter.sendComponent(player, TextComponent.of("Invalid value entered. '" + value + "' is not a valid value. Valid values are : true, false, undefined, 1, -1, or 0.", TextColor.RED));
return;
}
PermissionUtil.getInstance().setPermissionValue(subj, permission, tristateValue, contexts);
TextAdapter.sendComponent(player, TextComponent.builder("")
.append("Set permission ")
.append(permission, TextColor.AQUA)
.append(" to ")
.append(value, TextColor.GREEN)
.append(" on group ")
.append(subj.getFriendlyName(), TextColor.GOLD)
.append(".").build());
}
}

View File

@ -0,0 +1,144 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.permission.Context;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.ui.UIHelper;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_PERMISSION_PLAYER)
public class CommandClaimPermissionPlayer extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("cpp")
@Description("Sets a permission on a player with a claim context.")
@Syntax("<player> [<permission> <value>]")
@Subcommand("permission player")
public void execute(Player player, User user, @Optional String[] args) throws CommandException, InvalidCommandArgument {
String permission = null;
String value = null;
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (args.length > 0) {
if (args.length < 2) {
throw new InvalidCommandArgument();
}
permission = args[0];
if (!playerData.ignoreClaims && permission != null && !player.hasPermission(permission)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_ASSIGN_WITHOUT_HAVING);
return;
}
value = args[1];
}
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE,
ImmutableMap.of(
"type", claim.getType().getName()));
if (claim.isWilderness() && !playerData.canManageWilderness) {
GriefDefenderPlugin.sendMessage(player, message);
return;
} else if (claim.isAdminClaim() && !playerData.canManageAdminClaims) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(player);
Set<Context> contexts = new HashSet<>();
contexts.add(claim.getContext());
if (permission == null || value == null) {
// display current permissions for user
List<Component> permList = Lists.newArrayList();
Map<String, Boolean> permissions = PermissionUtil.getInstance().getPermissions(holder, contexts);
for (Map.Entry<String, Boolean> permissionEntry : permissions.entrySet()) {
Boolean permValue = permissionEntry.getValue();
Component permText = TextComponent.builder("")
.append(permissionEntry.getKey(), TextColor.GREEN)
.append(" ")
.append(permValue.toString(), TextColor.GOLD).build();
permList.add(permText);
}
List<Component> finalTexts = UIHelper.stripeText(permList);
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(TextComponent.of(user.getName() + " Permissions", TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(finalTexts);
paginationBuilder.sendTo(player);
return;
}
Tristate tristateValue = PermissionUtil.getInstance().getTristateFromString(value);
if (tristateValue == null) {
TextAdapter.sendComponent(player, TextComponent.of("Invalid value entered. '" + value + "' is not a valid value. Valid values are : true, false, undefined, 1, -1, or 0.", TextColor.RED));
return;
}
PermissionUtil.getInstance().setPermissionValue(holder, permission, tristateValue, contexts);
TextAdapter.sendComponent(player, TextComponent.builder("")
.append("Set permission ")
.append(permission, TextColor.AQUA)
.append(" to ")
.append(value, TextColor.GREEN)
.append(" on user ")
.append(user.getName(), TextColor.GOLD)
.append(".").build());
}
}

View File

@ -0,0 +1,154 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimSchematic;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.sql.Date;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_SCHEMATIC)
public class CommandClaimSchematic extends BaseCommand {
@CommandAlias("claimschematic")
@Description("Manages claim schematics. Use '/claimschematic create <name>' to create a live backup of claim.")
@Syntax("<create|delete> <name>")
@Subcommand("schematic")
public void execute(Player player, @Optional String[] args) throws CommandException, InvalidCommandArgument {
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() == null) {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_WORLDEDIT_MISSING);
return;
}
String action = null;
String name = null;
if (args.length > 0) {
action = args[0];
if (args.length < 2) {
throw new InvalidCommandArgument();
}
name = args[1];
}
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component denyMessage = claim.allowEdit(player);
if (denyMessage != null) {
GriefDefenderPlugin.sendMessage(player, denyMessage);
return;
}
if (action == null) {
if (claim.schematics.isEmpty()) {
TextAdapter.sendComponent(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SCHEMATIC_NONE));
return;
}
List<Component> schematicTextList = new ArrayList<>();
for (ClaimSchematic schematic : claim.schematics.values()) {
final String schematicName = schematic.getName();
final Instant schematicDate = schematic.getDateCreated();
schematicTextList.add(
TextComponent.builder("")
.append(schematicName, TextColor.GREEN)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(displayConfirmationConsumer(player, claim, schematic))))
.hoverEvent(HoverEvent.showText(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SCHEMATIC_RESTORE_CLICK,
ImmutableMap.of(
"name", TextComponent.of(schematicName, TextColor.GREEN),
"date", TextComponent.of(Date.from(schematicDate).toString(), TextColor.AQUA)))))
.build());
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(TextComponent.of("Schematics", TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(schematicTextList);
paginationBuilder.sendTo(player);
} else if (action.equalsIgnoreCase("create")) {
TextAdapter.sendComponent(player, TextComponent.of("Creating schematic backup...", TextColor.GREEN));
final ClaimSchematic schematic = ClaimSchematic.builder().claim(claim).name(name).build().orElse(null);
if (schematic != null) {
TextAdapter.sendComponent(player, TextComponent.of("Schematic backup complete.", TextColor.GREEN));
} else {
TextAdapter.sendComponent(player, TextComponent.of("Schematic could not be created.", TextColor.GREEN));
}
} else if (action.equalsIgnoreCase("delete")) {
claim.deleteSchematic(name);
TextAdapter.sendComponent(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SCHEMATIC_DELETED,
ImmutableMap.of("name", name)));
}
}
private static Consumer<CommandSource> displayConfirmationConsumer(CommandSource src, Claim claim, ClaimSchematic schematic) {
return confirm -> {
final Component schematicConfirmationText = TextComponent.builder("")
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(src, claim, schematic))))
.hoverEvent(HoverEvent.showText(GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SCHEMATIC_RESTORE_CONFIRMATION))).build();
TextAdapter.sendComponent(src, schematicConfirmationText);
};
}
private static Consumer<CommandSource> createConfirmationConsumer(CommandSource src, Claim claim, ClaimSchematic schematic) {
return confirm -> {
schematic.apply();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SCHEMATIC_RESTORE_CONFIRMED,
ImmutableMap.of("name", schematic.getName()));
GriefDefenderPlugin.sendMessage(src, message);
};
}
}

View File

@ -0,0 +1,129 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_SELL)
public class CommandClaimSell extends BaseCommand {
@CommandAlias("claimsell")
@Description("Puts your claim up for sale. Use /claimsell amount.\nNote: Requires economy plugin.")
@Syntax("<amount> | cancel")
@Subcommand("sell claim")
public void execute(Player player, String arg) throws InvalidCommandArgument {
if (!GriefDefenderPlugin.getInstance().economyService.isPresent()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_NOT_INSTALLED);
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (claim.isAdminClaim() || claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_NOT_FOR_SALE);
return;
}
if (!playerData.canIgnoreClaim(claim) && !player.getUniqueId().equals(claim.getOwnerUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_SALE);
return;
}
Double salePrice = null;
if (!claim.getEconomyData().isForSale()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_NOT_FOR_SALE);
return;
}
if (arg.equalsIgnoreCase("cancel")) {
claim.getEconomyData().setForSale(false);
claim.getEconomyData().setSalePrice(-1);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_SALE_CANCELLED);
return;
} else {
try {
salePrice = Double.parseDouble(arg);
} catch (NumberFormatException e) {
throw new InvalidCommandArgument();
}
}
if (salePrice == null || salePrice < 0) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_SALE_INVALID_PRICE,
ImmutableMap.of(
"amount", salePrice));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_SALE_CONFIRMATION,
ImmutableMap.of(
"amount", salePrice));
GriefDefenderPlugin.sendMessage(player, message);
final Component saleConfirmationText = TextComponent.builder("")
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createSaleConfirmationConsumer(player, claim, salePrice))))
.build();
GriefDefenderPlugin.sendMessage(player, saleConfirmationText);
}
private static Consumer<CommandSource> createSaleConfirmationConsumer(CommandSource src, Claim claim, double price) {
return confirm -> {
claim.getEconomyData().setSalePrice(price);
claim.getEconomyData().setForSale(true);
claim.getData().save();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_SALE_CONFIRMED,
ImmutableMap.of("amount", price));
GriefDefenderPlugin.sendMessage(src, message);
};
}
}

View File

@ -0,0 +1,154 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaimResult;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.transaction.ResultType;
import org.spongepowered.api.service.economy.transaction.TransactionResult;
import java.math.BigDecimal;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SELL_CLAIM_BLOCKS)
public class CommandClaimSellBlocks extends BaseCommand {
@CommandAlias("sellclaim|sellclaimblocks|sellblocks")
@Description("Sell your claim blocks for server money.\nNote: Requires economy plugin.")
@Syntax("[<amount>]")
@Subcommand("sell blocks")
public void execute(Player player, @Optional Integer blockCount) {
final boolean economyMode = GriefDefenderPlugin.getInstance().isEconomyModeEnabled();
// if economy is disabled, don't do anything
if (!GriefDefenderPlugin.getInstance().economyService.isPresent()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_NOT_INSTALLED);
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (playerData.getEconomyClaimBlockReturn() <= 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_BUY_SELL_DISABLED);
return;
}
// if selling disabled, send error message
if (playerData.getEconomyClaimBlockReturn() == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_ONLY_BUY);
return;
}
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(player.getUniqueId()).orElse(null);
if (playerAccount == null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_PLAYER_NOT_FOUND, ImmutableMap.of(
"player", player.getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
int availableBlocks = economyMode ? playerData.getAccruedClaimBlocks() + playerData.getBonusClaimBlocks() : playerData.getInternalRemainingClaimBlocks();
if (blockCount == null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_PURCHASE_COST,
ImmutableMap.of(
"amount", playerData.getEconomyClaimBlockReturn(),
"balance", availableBlocks));
GriefDefenderPlugin.sendMessage(player, message);
return;
} else {
// try to parse number of blocks
if (blockCount <= 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_BUY_INVALID);
return;
} else if (blockCount > availableBlocks) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_BLOCK_NOT_AVAILABLE);
return;
}
// attempt to compute value and deposit it
double economyTotalValue = blockCount * playerData.getEconomyClaimBlockReturn();
final Currency defaultCurrency = GriefDefenderPlugin.getInstance().economyService.get().getDefaultCurrency();
final TransactionResult result = playerAccount.deposit(defaultCurrency, BigDecimal.valueOf(economyTotalValue), Sponge.getCauseStackManager().getCurrentCause());
if (result.getResult() != ResultType.SUCCESS) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_SELL_ERROR, ImmutableMap.of(
"reason", result.getResult()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final BigDecimal currentFunds = playerAccount.getBalance(defaultCurrency);
Component message = null;
if (economyMode) {
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_BLOCK_SALE_CONFIRMATION,
ImmutableMap.of(
"deposit", economyTotalValue,
"balance", String.valueOf("$" + currentFunds),
"amount", playerData.getRemainingClaimBlocks()));
} else {
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_BLOCK_SALE_CONFIRMATION,
ImmutableMap.of(
"deposit", economyTotalValue,
"amount", playerData.getRemainingClaimBlocks()));
}
int bonusBlocks = playerData.getBonusClaimBlocks();
int accruedBlocks = playerData.getAccruedClaimBlocks();
if (bonusBlocks > 0) {
if (bonusBlocks >= blockCount) {
bonusBlocks = (int) (bonusBlocks - blockCount);
playerData.setBonusClaimBlocks(bonusBlocks);
} else {
int remaining = (int) (blockCount - bonusBlocks);
playerData.setBonusClaimBlocks(0);
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() - remaining);
}
} else {
accruedBlocks = (int) (accruedBlocks - blockCount);
playerData.setAccruedClaimBlocks(accruedBlocks);
}
playerData.saveAllData();
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -0,0 +1,66 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_SET_SPAWN)
public class CommandClaimSetSpawn extends BaseCommand {
@CommandAlias("claimsetspawn")
@Description("Sets the spawn of claim.")
@Subcommand("claim setspawn")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Component result = claim.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
final Vector3i pos = VecHelper.toVector3i(player.getLocation());
claim.getInternalClaimData().setSpawnPos(pos);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SPAWN_SET_SUCCESS,
ImmutableMap.of(
"location", pos));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,120 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_SPAWN)
public class CommandClaimSpawn extends BaseCommand {
@CommandAlias("claimspawn")
@Description("Teleports you to claim spawn if available.")
@Syntax("[name] [user]")
@Subcommand("claim spawn")
public void execute(Player player, @Optional String claimName, @Optional User targetPlayer) {
final GDPlayerData srcPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDPlayerData targetPlayerData = null;
if (targetPlayer != null) {
targetPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), targetPlayer.getUniqueId());
} else {
targetPlayerData = srcPlayerData;
}
GDClaim claim = null;
if (claimName != null) {
for (Claim playerClaim : targetPlayerData.getInternalClaims()) {
String name = null;
Component component = playerClaim.getName().orElse(null);
if (component != null) {
name = PlainComponentSerializer.INSTANCE.serialize(component);
if (claimName.equalsIgnoreCase(name)) {
claim = (GDClaim) playerClaim;
break;
}
}
}
if (claim == null) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_CLAIMNAME_NOT_FOUND,
ImmutableMap.of("name", claimName)));
return;
}
} else {
claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(targetPlayerData, player.getLocation());
}
if (!srcPlayerData.canIgnoreClaim(claim) && !claim.isUserTrusted(player, TrustTypes.ACCESSOR) && !player.hasPermission(GDPermissions.COMMAND_DELETE_CLAIMS)) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ACCESS,
ImmutableMap.of("player", claim.getOwnerName())));
return;
}
final Vector3i spawnPos = claim.getData().getSpawnPos().orElse(null);
if (spawnPos == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().SPAWN_NOT_SET);
return;
}
final Location<World> spawnLocation = new Location<>(claim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
int teleportDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PLAYER_TELEPORT_DELAY, claim);
if (teleportDelay > 0) {
srcPlayerData.teleportDelay = teleportDelay + 1;
srcPlayerData.teleportLocation = spawnLocation;
return;
}
player.setLocation(spawnLocation);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.SPAWN_TELEPORT,
ImmutableMap.of(
"location", spawnPos));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SUBDIVIDE_CLAIMS)
public class CommandClaimSubdivision extends BaseCommand {
@CommandAlias("modesubdivide|subdivideclaims|sc")
@Description("Switches the shovel tool to subdivision mode, used to subdivide your claims.")
@Subcommand("mode subdivide")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.shovelMode = ShovelTypes.SUBDIVISION;
playerData.claimSubdividing = null;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().MODE_SUBDIVISION);
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TOWN_MODE)
public class CommandClaimTown extends BaseCommand {
@CommandAlias("modetown")
@Description("Switches the shovel tool to town claims mode.")
@Subcommand("mode town")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.shovelMode = ShovelTypes.TOWN;
playerData.claimSubdividing = null;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().MODE_TOWN);
}
}

View File

@ -0,0 +1,86 @@
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimResult;
import com.griefdefender.api.claim.ClaimResultType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.data.PlayerData;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import java.util.UUID;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRANSFER_CLAIM)
public class CommandClaimTransfer extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("claimtransfer|transferclaim")
@Description("Transfers a basic or admin claim to another player.")
@Syntax("<player>")
@Subcommand("claim transfer")
public void execute(Player player, User targetPlayer) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (claim == null || claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_FOUND);
return;
}
final UUID ownerId = claim.getOwnerUniqueId();
final boolean isAdmin = playerData.canIgnoreClaim(claim);
// check permission
if (!isAdmin && claim.isAdminClaim() && !player.hasPermission(GDPermissions.COMMAND_ADMIN_CLAIMS)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_CLAIM_TRANSFER_ADMIN);
return;
} else if (!isAdmin && !player.getUniqueId().equals(ownerId) && claim.isUserTrusted(player, TrustTypes.MANAGER)) {
if (claim.parent == null) {
// Managers can only transfer child claims
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
} else if (!isAdmin && !claim.isAdminClaim() && !player.getUniqueId().equals(ownerId)) {
// verify ownership
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
// change ownership
GDCauseStackManager.getInstance().pushCause(player);
final ClaimResult claimResult = claim.transferOwner(targetPlayer.getUniqueId());
if (!claimResult.successful()) {
PlayerData targetPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), targetPlayer.getUniqueId());
if (claimResult.getResultType() == ClaimResultType.INSUFFICIENT_CLAIM_BLOCKS) {
TextAdapter.sendComponent(player, TextComponent.of("Could not transfer claim to player with UUID " + targetPlayer.getUniqueId() + "."
+ " Player only has " + targetPlayerData.getRemainingClaimBlocks() + " claim blocks remaining."
+ " The claim requires a total of " + claim.getClaimBlocks() + " claim blocks to own.", TextColor.RED));
} else if (claimResult.getResultType() == ClaimResultType.WRONG_CLAIM_TYPE) {
TextAdapter.sendComponent(player, TextComponent.of("The wilderness claim cannot be transferred.", TextColor.RED));
} else if (claimResult.getResultType() == ClaimResultType.CLAIM_EVENT_CANCELLED) {
TextAdapter.sendComponent(player, TextComponent.of("Could not transfer the claim. A plugin has cancelled the TransferClaimEvent.", TextColor.RED));
} else {
TextAdapter.sendComponent(player, TextComponent.of("Could not transfer the claim. " + claimResult.getResultType().name(), TextColor.RED));
}
} else {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_TRANSFER_SUCCESS));
}
}
}

View File

@ -0,0 +1,107 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.item.inventory.ItemStack;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.registry.BlockTypeRegistryModule;
import com.griefdefender.internal.registry.EntityTypeRegistryModule;
import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissions;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BAN)
public class CommandClaimUnban extends BaseCommand {
@CommandCompletion("@gdbantypes @gdmcids @gddummy")
@CommandAlias("claimunban")
@Description("Unbans target id allowing it to be used again.")
@Syntax("hand | <type> <target>")
@Subcommand("unban")
public void execute(Player player, String type, @Optional String id) {
if (type.equalsIgnoreCase("block")) {
if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_BLOCK_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.removeBlockBan(id);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_BLOCK,
ImmutableMap.of("id", id)));
} else if (type.equalsIgnoreCase("entity")) {
if (!EntityTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_ENTITY_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.removeEntityBan(id);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ENTITY,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("item")) {
if (!ItemTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_ITEM_NOT_FOUND,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
return;
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.removeItemBan(id);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("hand")) {
final ItemStack itemInHand = player.getItemInHand(HandTypes.MAIN_HAND).orElse(null);
if (itemInHand == null) {
return;
}
final String handItemId = itemInHand.getType().getId();
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.removeItemBan(handItemId);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(handItemId, TextColor.LIGHT_PURPLE))));
} else {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE,
ImmutableMap.of("type", type)));
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_WORLDEDIT)
public class CommandClaimWorldEdit extends BaseCommand {
@CommandAlias("claimwe|claimworldedit")
@Description("Uses the worldedit selection to create a claim.")
@Subcommand("claim worldedit|claim we")
public void execute(Player player) {
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_WORLDEDIT_MISSING);
return;
}
GriefDefenderPlugin.getInstance().getWorldEditProvider().createClaim(player);
}
}

View File

@ -0,0 +1,116 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GDDebugData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.User;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_ADMIN_DEBUG)
public class CommandDebug extends BaseCommand {
@CommandAlias("gddebug")
@Description("Captures all GD actions for debugging purposes.")
@Syntax("<record|paste|on|off> [filter]")
@Subcommand("debug")
public void execute(CommandSource src, String target, @Optional User user) {
GDDebugData debugData = null;
boolean paste = false;
if (target.equalsIgnoreCase("on")) {
debugData = getOrCreateDebugUser(src, user, true);
} else if (target.equalsIgnoreCase("record")) {
debugData = getOrCreateDebugUser(src, user, false);
} else if (target.equalsIgnoreCase("paste")) {
paste = true;
} else if (target.equalsIgnoreCase("off")) {
GriefDefenderPlugin.getInstance().getDebugUserMap().remove(src.getIdentifier());
if (GriefDefenderPlugin.getInstance().getDebugUserMap().isEmpty()) {
GriefDefenderPlugin.debugActive = false;
}
}
if (debugData == null) {
if (paste) {
debugData = GriefDefenderPlugin.getInstance().getDebugUserMap().get(src.getIdentifier());
if (debugData == null) {
TextAdapter.sendComponent(src, TextComponent.of("Nothing to paste!", TextColor.RED));
} else {
debugData.pasteRecords();
}
}
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(GriefDefenderPlugin.GD_TEXT)
.append("Debug ", TextColor.GRAY)
.append("OFF", TextColor.RED)
.build());
GriefDefenderPlugin.getInstance().getDebugUserMap().remove(src.getIdentifier());
if (GriefDefenderPlugin.getInstance().getDebugUserMap().isEmpty()) {
GriefDefenderPlugin.debugActive = false;
}
} else {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(GriefDefenderPlugin.GD_TEXT)
.append("Debug: ", TextColor.GRAY)
.append("ON", TextColor.GREEN)
.append(" | ")
.append("Verbose: ", TextColor.GRAY)
.append(!debugData.isRecording() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))
.append(" | ")
.append("Record: ", TextColor.GRAY)
.append(debugData.isRecording() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))
.append(" | ")
.append("User: ", TextColor.GRAY)
.append(user == null ? "ALL" : user.getName(), TextColor.GOLD)
.build());
GriefDefenderPlugin.getInstance().getDebugUserMap().put(src.getIdentifier(), debugData);
}
}
private GDDebugData getOrCreateDebugUser(CommandSource src, User user, boolean verbose) {
GDDebugData debugData = GriefDefenderPlugin.getInstance().getDebugUserMap().get(src.getIdentifier());
if (debugData == null) {
debugData = new GDDebugData(src, user, verbose);
GriefDefenderPlugin.getInstance().getDebugUserMap().put(src.getIdentifier(), debugData);
} else {
debugData.setTarget(user);
debugData.setVerbose(verbose);
}
GriefDefenderPlugin.debugActive = true;
return debugData;
}
}

View File

@ -0,0 +1,92 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import net.kyori.text.Component;
/**
* Thrown when an executed command raises an error or when execution of
* the command failed.
*/
public class CommandException extends ComponentMessageException {
private static final long serialVersionUID = 4626722485860074825L;
private final boolean includeUsage;
/**
* Constructs a new {@link CommandException} with the given message.
*
* @param message The detail message
*/
public CommandException(Component message) {
this(message, false);
}
/**
* Constructs a new {@link CommandException} with the given message and
* the given cause.
*
* @param message The detail message
* @param cause The cause
*/
public CommandException(Component message, Throwable cause) {
this(message, cause, false);
}
/**
* Constructs a new {@link CommandException} with the given message.
*
* @param message The detail message
* @param includeUsage Whether to include usage in the exception
*/
public CommandException(Component message, boolean includeUsage) {
super(message);
this.includeUsage = includeUsage;
}
/**
* Constructs a new {@link CommandException} with the given message and
* the given cause.
*
* @param message The detail message
* @param cause The cause
* @param includeUsage Whether to include the usage in the exception
*/
public CommandException(Component message, Throwable cause, boolean includeUsage) {
super(message, cause);
this.includeUsage = includeUsage;
}
/**
* Gets whether the exception should include usage in
* the presentation of the exception/stack-trace.
*
* @return Whether to include usage in the exception
*/
public boolean shouldIncludeUsage() {
return this.includeUsage;
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.command.CommandSource;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_RELOAD)
public class CommandGDReload extends BaseCommand {
@CommandAlias("gdreload")
@Description("Reloads GriefDefender's configuration settings.")
@Subcommand("reload")
public void execute(CommandSource src) {
GriefDefenderPlugin.getInstance().loadConfig();
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().PLUGIN_RELOAD);
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.PermissionService;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_VERSION)
public class CommandGDVersion extends BaseCommand {
@CommandAlias("gdversion")
@Description("Displays GriefDefender's version information.")
@Subcommand("version")
public void execute(CommandSource src) {
final String spongePlatform = Sponge.getPlatform().getContainer(org.spongepowered.api.Platform.Component.IMPLEMENTATION).getName();
Component gpVersion = TextComponent.builder("")
.append(GriefDefenderPlugin.GD_TEXT)
.append("Running ")
.append("GriefDefender " + GriefDefenderPlugin.IMPLEMENTATION_VERSION, TextColor.AQUA)
.build();
Component spongeVersion = TextComponent.builder("")
.append(GriefDefenderPlugin.GD_TEXT)
.append("Running ")
.append(spongePlatform + " " + GriefDefenderPlugin.SPONGE_VERSION, TextColor.YELLOW)
.build();
String permissionPlugin = Sponge.getServiceManager().getRegistration(PermissionService.class).get().getPlugin().getId();
String permissionVersion = Sponge.getServiceManager().getRegistration(PermissionService.class).get().getPlugin().getVersion().orElse("unknown");
Component permVersion = TextComponent.builder("")
.append(GriefDefenderPlugin.GD_TEXT)
.append("Running ")
.append(permissionPlugin + " " + permissionVersion, TextColor.GREEN)
.build();
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(gpVersion)
.append("\n")
.append(spongeVersion)
.append("\n")
.append(permVersion)
.build());
}
}

View File

@ -0,0 +1,92 @@
package com.griefdefender.command;
import java.util.function.Consumer;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_GIVE_BLOCKS)
public class CommandGiveBlocks extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("giveblocks")
@Description("Gives claim blocks to another player.")
@Syntax("<player> <amount>")
@Subcommand("giveblocks")
public void execute(Player src, User targetPlayer, int amount) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(src.getWorld(), src.getUniqueId());
int availableBlocks = playerData.getAccruedClaimBlocks() + playerData.getBonusClaimBlocks();
if (amount > availableBlocks) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_GIVEBLOCKS_NOT_ENOUGH,
ImmutableMap.of("amount", TextComponent.of(availableBlocks, TextColor.GOLD))));
return;
}
final Component confirmationText = TextComponent.builder()
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_GIVEBLOCKS_CONFIRMATION,
ImmutableMap.of("player", TextComponent.of(targetPlayer.getName(), TextColor.AQUA),
"amount", TextComponent.of(amount, TextColor.GREEN))))
.append(TextComponent.builder()
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(src, targetPlayer, amount))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(src, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(Player src, User targetPlayer, int amount) {
return confirm -> {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(src.getWorld(), src.getUniqueId());
final int accruedTotal = playerData.getAccruedClaimBlocks();
final int bonusTotal = playerData.getBonusClaimBlocks();
if (bonusTotal >= amount) {
playerData.setBonusClaimBlocks(bonusTotal - amount);
} else if (accruedTotal >= amount) {
playerData.setAccruedClaimBlocks(accruedTotal- amount);
} else {
int remaining = amount - bonusTotal;
playerData.setBonusClaimBlocks(0);
int newAccrued = accruedTotal - remaining;
playerData.setAccruedClaimBlocks(newAccrued);
}
final GDPlayerData targetPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(src.getWorld(), targetPlayer.getUniqueId());
targetPlayerData.setBonusClaimBlocks(targetPlayerData.getBonusClaimBlocks() + amount);
playerData.getStorageData().save();
targetPlayerData.getStorageData().save();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_GIVEBLOCKS_CONFIRMED);
TextAdapter.sendComponent(src, message);
if (targetPlayer.isOnline()) {
final Component targetMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_GIVEBLOCKS_RECEIVED,
ImmutableMap.of("amount", TextComponent.of(amount, TextColor.GOLD),
"player", TextComponent.of(src.getName(), TextColor.AQUA)));
TextAdapter.sendComponent((Player) targetPlayer, targetMessage);
}
};
}
}

View File

@ -0,0 +1,31 @@
package com.griefdefender.command;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_GIVE_PET)
public class CommandGivePet extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("givepet")
@Description("Transfers a pet to a new owner.")
@Syntax("<player>")
@Subcommand("givepet")
public void execute(Player player, User newOwner) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.petRecipientUniqueId = newOwner.getUniqueId();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_PET_TRANSFER_READY);
}
}

View File

@ -0,0 +1,51 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.HelpCommand;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandSource;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_HELP)
public class CommandHelp extends BaseCommand {
@HelpCommand
@Description("Displays GriefDefender command help.")
public void execute(CommandSource src) {
PaginationList.Builder paginationBuilder =
PaginationList.builder().title(TextComponent.of("Showing GriefDefender Help", TextColor.AQUA)).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(GriefDefenderPlugin.helpComponents);
paginationBuilder.sendTo(src);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.Description;
import com.griefdefender.internal.pagination.ActivePagination;
import com.griefdefender.internal.pagination.GDPaginationHolder;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
public class CommandPagination extends BaseCommand {
@CommandAlias("gd:pagination")
@Description("Used internally by GD for pagination purposes.")
public void execute(CommandSource src, String[] args) throws CommandException {
String id = args[0];
final ActivePagination activePagination = GDPaginationHolder.getInstance().getActivePagination(src, id);
if (activePagination == null) {
TextAdapter.sendComponent(src, TextComponent.of("Source " + src.getName() + " has no paginations!", TextColor.RED));
return;
}
String action = args[1];
if (action.equals("page")) {
activePagination.currentPage();
} else if (action.equals("next")) {
activePagination.nextPage();
} else if (action.equals("prev")) {
activePagination.previousPage();
} else {
int page = Integer.parseInt(action);
activePagination.specificPage(page);
}
}
}

View File

@ -0,0 +1,273 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PlayerUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.data.manipulator.mutable.entity.JoinData;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.world.storage.WorldProperties;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_PLAYER_INFO_BASE)
public class CommandPlayerInfo extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("playerinfo")
@Description("Gets information about a player.")
@Syntax("[<player>|<player> <world>]")
@Subcommand("player info")
public void execute(CommandSource src, @Optional String[] args) throws InvalidCommandArgument {
GDPermissionUser user = null;
WorldProperties worldProperties = null;
if (args.length > 0) {
user = PermissionHolderCache.getInstance().getOrCreateUser(args[0]);
if (user == null) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_PLAYER_NOT_FOUND,
ImmutableMap.of("player", args[0])));
return;
}
if (args.length > 1) {
worldProperties = Sponge.getServer().getWorldProperties(args[1]).orElse(null);
if (worldProperties == null) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_WORLD_NOT_FOUND,
ImmutableMap.of("world", args[1])));
return;
}
}
}
if (user == null) {
if (!(src instanceof Player)) {
GriefDefenderPlugin.sendMessage(src, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_INVALID_PLAYER));
return;
}
user = PermissionHolderCache.getInstance().getOrCreateUser((User) src);
if (worldProperties == null) {
worldProperties = ((Player) src).getWorld().getProperties();
}
}
if (worldProperties == null) {
worldProperties = Sponge.getServer().getDefaultWorld().get();
}
// otherwise if no permission to delve into another player's claims data or self
if ((user != null && user != src && !src.hasPermission(GDPermissions.COMMAND_PLAYER_INFO_OTHERS))) {
TextAdapter.sendComponent(src, MessageCache.getInstance().PERMISSION_PLAYER_VIEW_OTHERS);
}
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(worldProperties.getUniqueId(), user.getUniqueId());
boolean useGlobalData = BaseStorage.USE_GLOBAL_PLAYER_STORAGE;
List<Claim> claimList = new ArrayList<>();
for (Claim claim : playerData.getInternalClaims()) {
if (useGlobalData) {
claimList.add(claim);
} else {
if (claim.getWorldUniqueId().equals(worldProperties.getUniqueId())) {
claimList.add(claim);
}
}
}
Component claimSizeLimit = TextComponent.of("none", TextColor.GRAY);
if (playerData.getMaxClaimX(ClaimTypes.BASIC) != 0 || playerData.getMaxClaimY(ClaimTypes.BASIC) != 0 || playerData.getMaxClaimZ(ClaimTypes.BASIC) != 0) {
claimSizeLimit = TextComponent.of(playerData.getMaxClaimX(ClaimTypes.BASIC) + "," + playerData.getMaxClaimY(ClaimTypes.BASIC) + "," + playerData.getMaxClaimZ(ClaimTypes.BASIC), TextColor.GRAY);
}
final double claimableChunks = GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME ? (playerData.getRemainingClaimBlocks() / 65536.0) : (playerData.getRemainingClaimBlocks() / 256.0);
final Component uuidText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_UUID,
ImmutableMap.of("id", user.getUniqueId().toString()));
final Component worldText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_WORLD,
ImmutableMap.of("name", worldProperties.getWorldName()));
final Component sizeLimitText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_CLAIM_SIZE_LIMIT,
ImmutableMap.of("limit", claimSizeLimit));
final Component initialBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_INITIAL,
ImmutableMap.of("amount", String.valueOf(playerData.getInitialClaimBlocks())));
final Component accruedBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_ACCRUED,
ImmutableMap.of(
"amount", String.valueOf(playerData.getAccruedClaimBlocks()),
"block_amount", String.valueOf(playerData.getBlocksAccruedPerHour())));
final Component maxAccruedBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_MAX_ACCRUED,
ImmutableMap.of("amount", String.valueOf(playerData.getMaxAccruedClaimBlocks())));
final Component bonusBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_BONUS,
ImmutableMap.of("amount", String.valueOf(playerData.getBonusClaimBlocks())));
final Component remainingBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_REMAINING,
ImmutableMap.of("amount", String.valueOf(playerData.getRemainingClaimBlocks())));
final Component economyBlockAvailablePurchaseText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_ECONOMY_BLOCK_AVAILABLE_PURCHASE,
ImmutableMap.of("amount", String.valueOf(playerData.getRemainingClaimBlocks())));
final Component economyBlockCostText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_ECONOMY_BLOCK_COST,
ImmutableMap.of("amount", String.valueOf("$" + playerData.getInternalEconomyBlockCost())));
final Component economyBlockSellReturnText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_ECONOMY_BLOCK_SELL_RETURN,
ImmutableMap.of("amount", String.valueOf("$" + playerData.getEconomyClaimBlockReturn())));
final Component minMaxLevelText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_CLAIM_LEVEL,
ImmutableMap.of("level", String.valueOf(playerData.getMinClaimLevel() + "-" + playerData.getMaxClaimLevel())));
final Component abandonRatioText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_ABANDON_RETURN_RATIO,
ImmutableMap.of("ratio", String.valueOf(playerData.getAbandonedReturnRatio(ClaimTypes.BASIC))));
final Component totalTaxText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_TAX_TOTAL,
ImmutableMap.of("amount", String.valueOf(playerData.getInitialClaimBlocks())));
final Component totalBlockText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_BLOCK_TOTAL,
ImmutableMap.of("amount", String.valueOf(playerData.getInitialClaimBlocks())));
final Component totalClaimableChunkText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_CHUNK_TOTAL,
ImmutableMap.of("amount", String.valueOf(Math.round(claimableChunks * 100.0)/100.0)));
final Component totalClaimText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_CLAIM_TOTAL,
ImmutableMap.of("amount", String.valueOf(claimList.size())));
List<Component> claimsTextList = Lists.newArrayList();
claimsTextList.add(uuidText);
claimsTextList.add(worldText);
claimsTextList.add(sizeLimitText);
claimsTextList.add(initialBlockText);
claimsTextList.add(accruedBlockText);
claimsTextList.add(maxAccruedBlockText);
claimsTextList.add(bonusBlockText);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
claimsTextList.add(economyBlockAvailablePurchaseText);
claimsTextList.add(economyBlockCostText);
claimsTextList.add(economyBlockSellReturnText);
} else {
claimsTextList.add(remainingBlockText);
}
claimsTextList.add(minMaxLevelText);
claimsTextList.add(abandonRatioText);
final int townLimit = playerData.getCreateClaimLimit(ClaimTypes.TOWN);
final int basicLimit = playerData.getCreateClaimLimit(ClaimTypes.BASIC);
final int subLimit = playerData.getCreateClaimLimit(ClaimTypes.SUBDIVISION);
String townLimitText = townLimit < 0 ? "" : String.valueOf(townLimit);
String basicLimitText = basicLimit < 0 ? "" : String.valueOf(basicLimit);
String subLimitText = subLimit < 0 ? "" : String.valueOf(subLimit);
Component claimCreateLimits = TextComponent.builder("")
.append("TOWN", TextColor.GRAY)
.append(" : ")
.append(townLimitText, TextColor.GREEN)
.append(" BASIC", TextColor.GRAY)
.append(" : ")
.append(basicLimitText, TextColor.GREEN)
.append(" SUB", TextColor.GRAY)
.append(" : ")
.append(subLimitText, TextColor.GREEN)
.build();
claimsTextList.add(claimCreateLimits);
if (GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
Component townTaxRate = TextComponent.builder("")
.append("TOWN", TextColor.GRAY)
.append(" : ")
.append(String.valueOf(playerData.getTaxRate(ClaimTypes.TOWN)), TextColor.GREEN)
.build();
// TODO
//TextColors.GRAY, " BASIC", TextColors.WHITE, " : ", TextColors.GREEN, playerData.optionTaxRateTownBasic,
//TextColors.GRAY, " SUB", TextColors.WHITE, " : ", TextColors.GREEN, playerData.getTaxRate(type));
Component claimTaxRate = TextComponent.builder("")
.append("BASIC", TextColor.GRAY)
.append(" : ")
.append(String.valueOf(playerData.getTaxRate(ClaimTypes.BASIC)), TextColor.GREEN)
.append(" SUB", TextColor.GRAY)
.append(" : ")
.append(String.valueOf(playerData.getTaxRate(ClaimTypes.SUBDIVISION)), TextColor.GREEN)
.build();
String taxRate = "N/A";
if (src instanceof Player) {
Player player = (Player) src;
if (player.getUniqueId().equals(user.getUniqueId())) {
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (claim != null && !claim.isWilderness()) {
final double playerTaxRate = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.TAX_RATE, claim);
taxRate = String.valueOf(playerTaxRate);
}
}
}
final Component currentTaxRateText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_TAX_CURRENT_RATE,
ImmutableMap.of("rate", taxRate));
final Component globalTownTaxText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_TAX_GLOBAL_TOWN_RATE,
ImmutableMap.of("rate", townTaxRate));
final Component globalClaimTaxText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_TAX_GLOBAL_CLAIM_RATE,
ImmutableMap.of("rate", claimTaxRate));
claimsTextList.add(currentTaxRateText);
claimsTextList.add(globalTownTaxText);
claimsTextList.add(globalClaimTaxText);
claimsTextList.add(totalTaxText);
}
claimsTextList.add(totalBlockText);
claimsTextList.add(totalClaimableChunkText);
claimsTextList.add(totalClaimText);
JoinData joinData = user.getOfflinePlayer().getOrCreate(JoinData.class).orElse(null);
if (joinData != null && joinData.lastPlayed().exists()) {
Date lastActive = null;
try {
lastActive = Date.from(joinData.lastPlayed().get());
} catch(DateTimeParseException ex) {
// ignore
}
if (lastActive != null) {
claimsTextList.add(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYERINFO_UI_LAST_ACTIVE,
ImmutableMap.of("date", lastActive)));
}
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(MessageCache.getInstance().PLAYERINFO_UI_TITLE).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(claimsTextList);
paginationBuilder.sendTo(src);
}
}

View File

@ -0,0 +1,96 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_RESTORE_CLAIM)
public class CommandRestoreClaim extends BaseCommand {
@CommandAlias("restoreclaim|claimrestore")
@Description("Restores claim to its natural state. Use with caution.")
@Subcommand("claim restore")
public void execute(Player player) {
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_NOT_FOUND);
return;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_DELETE,
ImmutableMap.of(
"type", claim.getType().getName()));
if (!player.hasPermission(GDPermissions.DELETE_CLAIM_ADMIN)) {
GriefDefenderPlugin.sendMessage(player, message);
return;
}
displayConfirmationConsumer(player, claim);
}
private static void displayConfirmationConsumer(CommandSource src, GDClaim claim) {
final Component schematicConfirmationText = TextComponent.builder("")
.append("Are you sure you want to restore this claim?")
.append("\n[")
.append("Confirm", TextColor.GREEN)
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createConfirmationConsumer(src, claim))))
.hoverEvent(HoverEvent.showText(TextComponent.of("Clicking confirm will restore ENTIRE claim back to default world gen state. Use cautiously!"))).build();
TextAdapter.sendComponent(src, schematicConfirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(CommandSource src, GDClaim claim) {
return confirm -> {
BlockUtil.getInstance().restoreClaim(claim);
final Component message = MessageCache.getInstance().CLAIM_RESTORE_SUCCESS;
GriefDefenderPlugin.sendMessage(src, message);
};
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_RESTORE_NATURE)
public class CommandRestoreNature extends BaseCommand {
@CommandAlias("modenature")
@Description("Switches the shovel tool to restoration mode.")
@Subcommand("mode nature")
public void execute(Player player) {
if (true) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().FEATURE_NOT_AVAILABLE);
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.shovelMode = ShovelTypes.RESTORE;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().MODE_NATURE);
}
}

View File

@ -0,0 +1,115 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_ACCRUED_CLAIM_BLOCKS)
public class CommandSetAccruedClaimBlocks extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("scb|setaccruedblocks")
@Description("Updates a player's accrued claim block total.")
@Syntax("<player> <amount> [world]")
@Subcommand("player setaccruedblocks")
public void execute(CommandSource src, String player, int amount, @Optional String worldName) throws InvalidCommandArgument {
GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
if (user == null) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_PLAYER_NOT_FOUND,
ImmutableMap.of("player", player)));
return;
}
World world = null;
if (worldName != null) {
world = Sponge.getServer().getWorld(worldName).orElse(null);
if (world == null) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_WORLD_NOT_FOUND,
ImmutableMap.of("world", worldName)));
return;
}
} else {
if (src instanceof Player) {
world = ((Player) src).getWorld();
} else {
// use default
world = Sponge.getServer().getWorlds().iterator().next();
}
if (world == null) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_WORLD_NOT_FOUND,
ImmutableMap.of("world", worldName)));
return;
}
}
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// set player's blocks
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world.getUniqueId(), user.getUniqueId());
if (!playerData.setAccruedClaimBlocks(amount)) {
TextAdapter.sendComponent(src, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PLAYER_ACCRUED_BLOCKS_EXCEEDED,
ImmutableMap.of(
"player", user.getName(),
"total", playerData.getAccruedClaimBlocks(),
"amount", amount)));
return;
}
playerData.getStorageData().save();
GriefDefenderPlugin.sendMessage(src, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_ACCRUED_BLOCKS_SUCCESS,
ImmutableMap.of(
"player", user.getName(),
"total", playerData.getAccruedClaimBlocks(),
"amount", amount)));
}
}

View File

@ -0,0 +1,63 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TOWN_CHAT)
public class CommandTownChat extends BaseCommand {
@CommandAlias("townchat")
@Description("Toggles town chat.")
@Subcommand("town chat")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(player.getLocation());
if (!claim.isInTown()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_NOT_IN);
return;
}
playerData.townChat = !playerData.townChat;
// toggle ignore claims mode on or off
if (!playerData.townChat) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_CHAT_DISABLED);
} else {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_CHAT_ENABLED);
}
}
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TOWN_TAG)
public class CommandTownTag extends BaseCommand {
@CommandAlias("towntag")
@Description("Sets the tag of your town.")
@Syntax("<tag>")
@Subcommand("town tag")
public void execute(Player player, String tag) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (claim == null || !claim.isInTown()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TOWN_NOT_IN);
return;
}
final GDClaim town = claim.getTownClaim();
final Component result = town.allowEdit(player);
if (result != null) {
GriefDefenderPlugin.sendMessage(player, result);
return;
}
TextComponent name = LegacyComponentSerializer.legacy().deserialize(tag, '&');
if (name == TextComponent.empty() || name.content().equals("clear")) {
town.getTownData().setTownTag(null);
} else {
town.getTownData().setTownTag(name);
}
town.getInternalClaimData().setRequiresSave(true);
Component resultMessage = null;
if (!claim.getTownData().getTownTag().isPresent()) {
resultMessage = MessageCache.getInstance().TOWN_TAG_CLEAR;
} else {
resultMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.TOWN_TAG,
ImmutableMap.of(
"tag", name));
}
TextAdapter.sendComponent(player, resultMessage);
}
}

View File

@ -0,0 +1,145 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDGroupTrustClaimEvent;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRUST_GROUP)
public class CommandTrustGroup extends BaseCommand {
@CommandCompletion("@gdgroups @gdtrusttypes @gddummy")
@CommandAlias("trustgroup")
@Description("Grants a group access to your claim."
+ "\nAccessor: access to interact with all blocks except inventory."
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<group> <accessor|builder|container|manager>")
@Subcommand("trust group")
public void execute(Player player, String groupName, String type) {
final TrustType trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(groupName);
if (group == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_GROUP, ImmutableMap.of(
"group", groupName)));
return;
}
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(player.getWorld().getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// determine which claim the player is standing in
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (!playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_COMMAND_TRUST);
return;
}
//check permission here
if(claim.allowGrantPermission(player) != null) {
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_TRUST,
ImmutableMap.of(
"owner", claim.getOwnerName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDGroupTrustClaimEvent.Remove event =
new GDGroupTrustClaimEvent.Remove(claim, ImmutableList.of(group.getName()), TrustTypes.NONE);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", group))));
return;
}
final String permission = CommandHelper.getTrustPermission(trustType);
Set<Context> contexts = new HashSet<>();
contexts.add(claim.getContext());
final List<String> groupTrustList = claim.getGroupTrustList(trustType);
if (!groupTrustList.contains(group.getName())) {
groupTrustList.add(group.getName());
} else {
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_ALREADY_HAS,
ImmutableMap.of(
"target", group.getName(),
"type", trustType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
PermissionUtil.getInstance().setPermissionValue(group, permission, Tristate.TRUE, contexts);
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_GRANT, ImmutableMap.of(
"target", group.getName(),
"type", trustType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,132 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDGroupTrustClaimEvent;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRUSTALL_GROUP)
public class CommandTrustGroupAll extends BaseCommand {
@CommandCompletion("@gdgroups @gdtrusttypes @gddummy")
@CommandAlias("trustallgroup")
@Description("Grants a group access to all your claims."
+ "\nAccessor: access to interact with all blocks except inventory."
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<group> <accessor|builder|container|manager>")
@Subcommand("trustall group")
public void execute(Player player, String target, String type) {
final TrustType trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(target);
// validate player argument
if (group == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_GROUP, ImmutableMap.of(
"group", target)));
return;
}
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
Set<Claim> claimList = null;
if (playerData != null) {
claimList = playerData.getInternalClaims();
}
if (playerData == null || claimList == null || claimList.size() == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_NO_CLAIMS);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDGroupTrustClaimEvent.Add
event = new GDGroupTrustClaimEvent.Add(new ArrayList<>(claimList), ImmutableList.of(group.getName()), trustType);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", group))));
return;
}
for (Claim claim : claimList) {
this.addAllGroupTrust(claim, group, trustType);
}
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_INDIVIDUAL_ALL_CLAIMS,
ImmutableMap.of(
"player", group.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
private void addAllGroupTrust(Claim claim, GDPermissionGroup holder, TrustType trustType) {
GDClaim gdClaim = (GDClaim) claim;
List<String> trustList = gdClaim.getGroupTrustList(trustType);
if (!trustList.contains(holder.getFriendlyName())) {
trustList.add(holder.getFriendlyName());
}
gdClaim.getInternalClaimData().setRequiresSave(true);
gdClaim.getInternalClaimData().save();
for (Claim child : gdClaim.children) {
this.addAllGroupTrust(child, holder, trustType);
}
}
}

View File

@ -0,0 +1,253 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_LIST_TRUST)
public class CommandTrustList extends BaseCommand {
@CommandAlias("trustlist")
@Description("Lists permissions for the claim you're standing in.")
@Subcommand("trust list")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
showTrustList(player, claim, TrustTypes.NONE);
}
public static void showTrustList(CommandSource src, GDClaim claim, TrustType type) {
final Component whiteOpenBracket = TextComponent.of("[", TextColor.AQUA);
final Component whiteCloseBracket = TextComponent.of("]", TextColor.AQUA);
final Component showAllText = MessageCache.getInstance().TRUST_CLICK_SHOW_LIST;
final Component showAccessorText = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", MessageCache.getInstance().TITLE_ACCESSOR.color(TextColor.YELLOW)));
final Component showContainerText = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", MessageCache.getInstance().TITLE_CONTAINER.color(TextColor.LIGHT_PURPLE)));
final Component showBuilderText = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", MessageCache.getInstance().TITLE_BUILDER.color(TextColor.GREEN)));
final Component showManagerText = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.UI_CLICK_FILTER_TYPE,
ImmutableMap.of("type", MessageCache.getInstance().TITLE_MANAGER.color(TextColor.GOLD)));
final Component allTypeText = TextComponent.builder("")
.append(type == TrustTypes.NONE ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("ALL")
.append(whiteCloseBracket)
.build() : TextComponent.builder("")
.append("ALL",TextColor.GRAY)
.build())
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createTrustConsumer(src, claim, TrustTypes.NONE))))
.hoverEvent(HoverEvent.showText(showAllText)).build();
final Component accessorTrustText = TextComponent.builder("")
.append(type == TrustTypes.ACCESSOR ? TextComponent.builder("")
.append(whiteOpenBracket)
.append(MessageCache.getInstance().TITLE_ACCESSOR.color(TextColor.YELLOW))
.append(whiteCloseBracket)
.build() : MessageCache.getInstance().TITLE_ACCESSOR.color(TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createTrustConsumer(src, claim, TrustTypes.ACCESSOR))))
.hoverEvent(HoverEvent.showText(showAccessorText)).build();
final Component builderTrustText = TextComponent.builder("")
.append(type == TrustTypes.BUILDER ? TextComponent.builder("")
.append(whiteOpenBracket)
.append(MessageCache.getInstance().TITLE_BUILDER.color(TextColor.GREEN))
.append(whiteCloseBracket)
.build() : MessageCache.getInstance().TITLE_BUILDER.color(TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createTrustConsumer(src, claim, TrustTypes.BUILDER))))
.hoverEvent(HoverEvent.showText(showBuilderText)).build();
final Component containerTrustText = TextComponent.builder("")
.append(type == TrustTypes.CONTAINER ? TextComponent.builder("")
.append(whiteOpenBracket)
.append(MessageCache.getInstance().TITLE_CONTAINER.color(TextColor.LIGHT_PURPLE))
.append(whiteCloseBracket)
.build() : MessageCache.getInstance().TITLE_CONTAINER.color(TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createTrustConsumer(src, claim, TrustTypes.CONTAINER))))
.hoverEvent(HoverEvent.showText(showContainerText)).build();
final Component managerTrustText = TextComponent.builder("")
.append(type == TrustTypes.MANAGER ? TextComponent.builder("")
.append(whiteOpenBracket)
.append("MANAGER", TextColor.GOLD)
.append(whiteCloseBracket)
.build() : MessageCache.getInstance().TITLE_MANAGER.color(TextColor.GRAY))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createTrustConsumer(src, claim, TrustTypes.MANAGER))))
.hoverEvent(HoverEvent.showText(showManagerText)).build();
final Component claimTrustHead = TextComponent.builder()
.append(" ")
.append(MessageCache.getInstance().LABEL_DISPLAYING.color(TextColor.AQUA))
.append(" ")
.append(allTypeText)
.append(" ")
.append(accessorTrustText)
.append(" ")
.append(builderTrustText)
.append(" ")
.append(containerTrustText)
.append(" ")
.append(managerTrustText)
.build();
List<UUID> userIdList = new ArrayList<>(claim.getUserTrusts());
List<Component> trustList = new ArrayList<>();
trustList.add(TextComponent.empty());
if (type == TrustTypes.NONE) {
// check highest trust first
for (UUID uuid : claim.getInternalClaimData().getManagers()) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
trustList.add(TextComponent.of(user.getName(), TextColor.GOLD));
userIdList.remove(user.getUniqueId());
}
for (UUID uuid : claim.getInternalClaimData().getBuilders()) {
if (!userIdList.contains(uuid)) {
continue;
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
trustList.add(TextComponent.of(user.getName(), TextColor.GREEN));
userIdList.remove(uuid);
}
/*for (String group : claim.getInternalClaimData().getManagerGroups()) {
permissions.append(SPACE_TEXT, Text.of(group));
}*/
for (UUID uuid : claim.getInternalClaimData().getContainers()) {
if (!userIdList.contains(uuid)) {
continue;
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
trustList.add(TextComponent.of(user.getName(), TextColor.LIGHT_PURPLE));
userIdList.remove(uuid);
}
/* for (String group : claim.getInternalClaimData().getBuilderGroups()) {
permissions.append(SPACE_TEXT, Text.of(group));
}*/
for (UUID uuid : claim.getInternalClaimData().getAccessors()) {
if (!userIdList.contains(uuid)) {
continue;
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
trustList.add(TextComponent.of(user.getName(), TextColor.YELLOW));
userIdList.remove(uuid);
}
/*for (String group : claim.getInternalClaimData().getContainerGroups()) {
permissions.append(SPACE_TEXT, Text.of(group));
}
player.sendMessage(permissions.build());
permissions = Text.builder(">").color(TextColors.BLUE);
for (UUID uuid : claim.getInternalClaimData().getAccessors()) {
User user = GriefDefenderPlugin.getOrCreateUser(uuid);
permissions.append(SPACE_TEXT, Text.of(user.getName()));
}
for (String group : claim.getInternalClaimData().getAccessorGroups()) {
permissions.append(SPACE_TEXT, Text.of(group));
}*/
} else {
for (UUID uuid : claim.getUserTrusts(type)) {
if (!userIdList.contains(uuid)) {
continue;
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
trustList.add(TextComponent.of(user.getName(), getTrustColor(type)));
userIdList.remove(uuid);
}
}
int fillSize = 20 - (trustList.size() + 2);
for (int i = 0; i < fillSize; i++) {
trustList.add(TextComponent.of(" "));
}
PaginationList.Builder paginationBuilder = PaginationList.builder()
.title(claimTrustHead).padding(TextComponent.of(" ").decoration(TextDecoration.STRIKETHROUGH, true)).contents(trustList);
paginationBuilder.sendTo(src);
paginationBuilder.sendTo(src);
}
private static TextColor getTrustColor(TrustType type) {
if (type == TrustTypes.NONE) {
return TextColor.WHITE;
}
if (type == TrustTypes.ACCESSOR) {
return TextColor.YELLOW;
}
if (type == TrustTypes.BUILDER) {
return TextColor.GREEN;
}
if (type == TrustTypes.CONTAINER) {
return TextColor.LIGHT_PURPLE;
}
return TextColor.GOLD;
}
private static Consumer<CommandSource> createTrustConsumer(CommandSource src, GDClaim claim, TrustType type) {
return consumer -> {
showTrustList(src, claim, type);
};
}
}

View File

@ -0,0 +1,167 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDUserTrustClaimEvent;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import java.util.List;
import java.util.UUID;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRUST_PLAYER)
public class CommandTrustPlayer extends BaseCommand {
@CommandCompletion("@gdplayers @gdtrusttypes @gddummy")
@CommandAlias("trust")
@Description("Grants a player access to your claim."
+ "\nAccessor: access to interact with all blocks except inventory."
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<player> [<accessor|builder|container|manager>]")
@Subcommand("trust player")
public void execute(Player player, String target, @Optional String type) {
TrustType trustType = null;
if (type == null) {
trustType = TrustTypes.BUILDER;
} else {
trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
}
GDPermissionUser user = null;
if (target.equalsIgnoreCase("public")) {
user = GriefDefenderPlugin.PUBLIC_USER;
} else {
user = PermissionHolderCache.getInstance().getOrCreateUser(target);
}
if (user == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_PLAYER,
ImmutableMap.of(
"player", target)));
return;
}
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(player.getWorld().getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// determine which claim the player is standing in
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (!claim.getOwnerUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_COMMAND_TRUST);
return;
}
if (user.getUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_SELF);
return;
}
if (user != null && claim.getOwnerUniqueId().equals(user.getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_OWNER_ALREADY);
return;
} else {
//check permission here
if(claim.allowGrantPermission(player) != null) {
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_TRUST,
ImmutableMap.of(
"player", claim.getOwnerName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
if(trustType == TrustTypes.MANAGER) {
Component denyReason = claim.allowEdit(player);
if(denyReason != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GRANT);
return;
}
}
}
GDCauseStackManager.getInstance().pushCause(player);
GDUserTrustClaimEvent.Add
event =
new GDUserTrustClaimEvent.Add(claim, ImmutableList.of(user.getUniqueId()), trustType);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", user.getName())))));
return;
}
final List<UUID> trustList = claim.getUserTrustList(trustType);
if (trustList.contains(user.getUniqueId())) {
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_ALREADY_HAS,
ImmutableMap.of(
"target", user.getName(),
"type", trustType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
trustList.add(user.getUniqueId());
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_GRANT, ImmutableMap.of(
"target", user.getName(),
"type", trustType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,151 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDUserTrustClaimEvent;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRUSTALL_PLAYER)
public class CommandTrustPlayerAll extends BaseCommand {
@CommandCompletion("@gdplayers @gdtrusttypes @gddummy")
@CommandAlias("trustall")
@Description("Grants a player access to all your claims."
+ "\nAccessor: access to interact with all blocks except inventory."
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<player> <accessor|builder|container|manager>")
@Subcommand("trustall player")
public void execute(Player player, String target, @Optional String type) {
TrustType trustType = null;
if (type == null) {
trustType = TrustTypes.BUILDER;
} else {
trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
}
GDPermissionUser user;
if (target.equalsIgnoreCase("public")) {
user = GriefDefenderPlugin.PUBLIC_USER;
} else {
user = PermissionHolderCache.getInstance().getOrCreateUser(target);
}
// validate player argument
if (user == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_PLAYER,
ImmutableMap.of(
"player", target)));
return;
}
if (user.getUniqueId().equals(player.getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_SELF);
return;
}
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
Set<Claim> claimList = null;
if (playerData != null) {
claimList = playerData.getInternalClaims();
}
if (playerData == null || claimList == null || claimList.size() == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_NO_CLAIMS);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDUserTrustClaimEvent.Add
event = new GDUserTrustClaimEvent.Add(new ArrayList<>(claimList), ImmutableList.of(user.getUniqueId()), trustType);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", user.getName()))));
return;
}
for (Claim claim : claimList) {
this.addAllUserTrust(claim, user, trustType);
}
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_INDIVIDUAL_ALL_CLAIMS,
ImmutableMap.of(
"player", user.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
private void addAllUserTrust(Claim claim, GDPermissionUser user, TrustType trustType) {
GDClaim gdClaim = (GDClaim) claim;
List<UUID> trustList = gdClaim.getUserTrustList(trustType);
if (!trustList.contains(user.getUniqueId())) {
trustList.add(user.getUniqueId());
}
gdClaim.getInternalClaimData().setRequiresSave(true);
gdClaim.getInternalClaimData().save();
for (Claim child : gdClaim.children) {
this.addAllUserTrust(child, user, trustType);
}
}
}

View File

@ -0,0 +1,115 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDGroupTrustClaimEvent;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.permission.Subject;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_UNTRUST_GROUP)
public class CommandUntrustGroup extends BaseCommand {
@CommandCompletion("@gdgroups @gddummy")
@CommandAlias("untrustgroup")
@Description("Revokes group access to your claim.")
@Syntax("<group>")
@Subcommand("untrust group")
public void execute(Player player, String target) {
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(target);
if (group == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_GROUP, ImmutableMap.of(
"group", target)));
return;
}
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(player.getWorld().getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// determine which claim the player is standing in
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (!playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_COMMAND_TRUST);
return;
}
//check permission here
if(claim.allowGrantPermission(player) != null) {
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_TRUST,
ImmutableMap.of(
"player", claim.getOwnerName()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDGroupTrustClaimEvent.Remove event =
new GDGroupTrustClaimEvent.Remove(claim, ImmutableList.of(group.getName()), TrustTypes.NONE);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", group))));
return;
}
claim.removeAllTrustsFromGroup(group.getName());
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UNTRUST_INDIVIDUAL_SINGLE_CLAIM,
ImmutableMap.of(
"target", group));
GriefDefenderPlugin.sendMessage(player, message);
}
}

View File

@ -0,0 +1,118 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDGroupTrustClaimEvent;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
import java.util.ArrayList;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_UNTRUSTALL_GROUP)
public class CommandUntrustGroupAll extends BaseCommand {
@CommandCompletion("@gdgroups @gdtrusttypes @gddummy")
@CommandAlias("untrustallgroup")
@Description("Revokes group access to all your claims")
@Syntax("<group>")
@Subcommand("untrustall group")
public void execute(Player player, String target, String type) {
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(target);
// validate player argument
if (group == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_GROUP,
ImmutableMap.of(
"group", target)));
return;
}
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
Set<Claim> claimList = null;
if (playerData != null) {
claimList = playerData.getInternalClaims();
}
if (playerData == null || claimList == null || claimList.size() == 0) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_NO_CLAIMS);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDGroupTrustClaimEvent.Remove
event = new GDGroupTrustClaimEvent.Remove(new ArrayList<>(claimList), ImmutableList.of(group.getName()), TrustTypes.NONE);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", group))));
return;
}
for (Claim claim : claimList) {
this.removeAllGroupTrust(claim, group);
}
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UNTRUST_INDIVIDUAL_ALL_CLAIMS,
ImmutableMap.of(
"player", group.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
private void removeAllGroupTrust(Claim claim, GDPermissionGroup holder) {
GDClaim gdClaim = (GDClaim) claim;
gdClaim.removeAllTrustsFromGroup(holder.getName());
gdClaim.getInternalClaimData().setRequiresSave(true);
gdClaim.getInternalClaimData().save();
for (Claim child : gdClaim.children) {
this.removeAllGroupTrust(child, holder);
}
}
}

View File

@ -0,0 +1,121 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDUserTrustClaimEvent;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.Component;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_UNTRUST_PLAYER)
public class CommandUntrustPlayer extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("untrust|ut")
@Description("Revokes player access to your claim.")
@Syntax("<player>")
@Subcommand("untrust player")
public void execute(Player player, String target) {
GDPermissionUser user;
if (target.equalsIgnoreCase("public")) {
user = GriefDefenderPlugin.PUBLIC_USER;
} else {
user = PermissionHolderCache.getInstance().getOrCreateUser(target);
}
if (user == null) {
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_PLAYER,
ImmutableMap.of(
"player", target)));
return;
}
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(player.getWorld().getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_DISABLED_WORLD);
return;
}
// determine which claim the player is standing in
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (!claim.getOwnerUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim) && claim.allowEdit(player) != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_COMMAND_TRUST);
return;
}
if (user.getUniqueId().equals(player.getUniqueId()) && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().UNTRUST_SELF);
return;
}
if (claim.getOwnerUniqueId().equals(user.getUniqueId())) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIM_OWNER_ALREADY);
return;
}
GDCauseStackManager.getInstance().pushCause(player);
GDUserTrustClaimEvent.Remove
event =
new GDUserTrustClaimEvent.Remove(claim, ImmutableList.of(user.getUniqueId()), TrustTypes.NONE);
GriefDefender.getEventManager().post(event);
GDCauseStackManager.getInstance().popCause();
if (event.cancelled()) {
TextAdapter.sendComponent(player, event.getMessage().orElse(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.TRUST_PLUGIN_CANCEL,
ImmutableMap.of("target", user.getName()))));
return;
}
claim.removeAllTrustsFromUser(user.getUniqueId());
claim.getInternalClaimData().setRequiresSave(true);
claim.getInternalClaimData().save();
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.UNTRUST_INDIVIDUAL_SINGLE_CLAIM,
ImmutableMap.of(
"target", user.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}

Some files were not shown because too many files have changed in this diff Show More