Merge branch 'v5' into features/v5/road-respect-flags

# Conflicts:
#	Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java
This commit is contained in:
dordsor21 2020-07-01 14:12:16 +01:00
commit 82a887fd3b
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
196 changed files with 7452 additions and 4927 deletions

2
.github/FUNDING.yml vendored
View File

@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] custom: https://www.paypal.me/AlexanderBrandes # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -28,6 +28,7 @@ assignees: ''
<!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here --> <!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here -->
<!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml --> <!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml -->
<!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. --> <!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. -->
**/plot debugpaste:**
### Server type: ### Server type:
**Select one** **Select one**

View File

@ -1,101 +0,0 @@
---
name: Bug/Issue report for PlotSquared
about: Bug / Issue report about this plugin
title: ''
labels: "[?] Testing Required"
assignees: ''
---
<!--- READ THIS BEFORE SUBMITTING AN ISSUE REPORT!!! -->
<!--- ##### DO NOT REMOVE THIS TEMPLATE! YOUR ISSUE *WILL* FIT IN IT! ##### -->
<!--- # NOTICE:
**Feature requests & Suggestions are to be submitted at the [PlotSquared Suggestions tracker](https://github.com/IntellectualSites/PlotSquaredSuggestions)**
**Code contributions are to be done through [PRs](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request), tagging the specific issue ticket(s) if applicable.**
**[DISCORD INVITE LINK](https://discord.gg/KxkjDVg)**
-->
# Bug Report Template:
<!--- Incomplete reports will most likely be marked as invalid, and closed, with few exceptions.-->
## Required Information section:
> ALL FIELDS IN THIS SECTION ARE REQUIRED, and must contain appropriate information
### Server config info (/plot debugpaste / file paste links):
<!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here -->
<!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml -->
<!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. -->
**/plot debugpaste:**
### Server type:
**Select one**
<!-- Select the type you are reporting the issue for (put an "X" between of brackets): -->
- [] Spigot / Paper *(CraftBukkit should not be used, re-test with Spigot first!)*
- [] Sponge
- [] NukkitX
### PlotSquared version:
<!-- Run /plot plugin in-game or in console & paste the full output here: -->
```
Paste the output here, between the tick marks, replacing this text
```
### Minecraft Version:
**Select one**
<!-- Select the type you are reporting the issue for (put an "X" between of brackets) -->
- [] Minecraft 1.15.2
- [] Minecraft 1.14.4
- [] Minecraft 1.13.2
- [] Minecraft 1.12.2
- [] Minecraft 1.11.2
- [] Minecraft 1.10.2
- [] Minecraft 1.9.4
- [] Minecraft 1.8.8
- [] Minecraft Java Edition *other versions, please specify*:
- [] Minecraft Bedrock Edition *specify version*:
- [] Minecraft Sponge *specify version*:
### Server build info:
<!--- Run /version in-game or in console & paste the full output here: -->
```
Paste the output here, between the tick marks, replacing this text
```
### WorldEdit/FAWE versions:
<!--- Specify which plugin you are using, and add its version. Either use /fawe version or /we version -->
- [] FAWE version:
- [] WorldEdit version:
### Description of the problem:
<!--- Be as specific as possible. Don't lie, redact information, or use false names/situations. -->
<!--- Who, What, When, Where, Why, How, Expected behavior, Resultant behavior, etc -->
### How to replicate:
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
## Additional Information:
> The information here is optional for you to provide, however it may help us to more readily diagnose any compatibility and bug issues.
### Other plugins being used on the server:
<!--- Optional but recommended - issue "/plugins" in-game or in console and copy/paste the list -->
### Relevant console output, log lines, and/or screenshots:
<!--- Please use in-line code insertion
```
like this
```
for short (20 lines or less) text blobs, or a paste service for large blobs -->
### Additional relevant comments/remarks:
<!--- Use this space to give us any additional information which may be relevant to this issue, such as: if you are using a Minecraft hosting provider; unusual installation environment; etc -->
# AFFIRMATION OF COMPLETION:
<!-- Make sure you have completed the following steps (put an "X" between of brackets): -->
- [] I included all information required in the sections above
- [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues?utf8=%E2%9C%93&q=is%3Aissue)
- [] I made sure I am using an up-to-date version of PlotSquared
- [] I made sure the bug/error is not caused by any other plugin
- [x] I didn't read but checked everything above.

View File

@ -1,5 +1,8 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: PlotSquared Issue Tracker
url: https://issues.intellectualsites.com/projects/ps
about: Click here to move to our new issue tracker
- name: PlotSquared Suggestions - name: PlotSquared Suggestions
url: https://github.com/IntellectualSites/PlotSquaredSuggestions url: https://github.com/IntellectualSites/PlotSquaredSuggestions
about: If you want to submit feature or suggestion ideas, do that here about: If you want to submit feature or suggestion ideas, do that here

View File

@ -2,10 +2,10 @@
<!-- Please describe which issue this Pull Request targets <!-- Please describe which issue this Pull Request targets
If there is no issue, please create one so we can look into it before approving your PR. If there is no issue, please create one so we can look into it before approving your PR.
You can do so here: https://github.com/IntellectualSites/PlotSquared/issues/new/choose You can do so here: https://issues.intellectualsites.com/projects/ps
--> -->
**Fixes #{issue number}** **Fixes {Link to issue}**
## Description ## Description

1
.gitignore vendored
View File

@ -142,3 +142,4 @@ p2error.txt
*.bat *.bat
Nukkit/build/resources/main/plugin.yml Nukkit/build/resources/main/plugin.yml
docs/ docs/
build/

View File

@ -11,7 +11,9 @@ repositories {
name = "papermc" name = "papermc"
url = "https://papermc.io/repo/repository/maven-public/" url = "https://papermc.io/repo/repository/maven-public/"
} }
maven { url = "https://ci.ender.zone/plugin/repository/everything/" }
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" } maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
maven { url = "https://repo.wea-ondara.net/repository/public/" }
mavenLocal() mavenLocal()
} }
@ -20,17 +22,24 @@ dependencies {
implementation(project(":PlotSquared-Core")) implementation(project(":PlotSquared-Core"))
compile("org.bstats:bstats-bukkit:1.7") compile("org.bstats:bstats-bukkit:1.7")
compile(project(":PlotSquared-Core")) compile(project(":PlotSquared-Core"))
compile("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT") compile("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT")
//implementation 'com.onarandombox.multiversecore:Multiverse-Core:3.0.0-SNAPSHOT' //implementation 'com.onarandombox.multiversecore:Multiverse-Core:3.0.0-SNAPSHOT'
implementation("org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT") implementation("org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT")
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.0.1") compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.1.0") {
exclude(module: "bukkit")
}
compile("io.papermc:paperlib:1.0.2") compile("io.papermc:paperlib:1.0.2")
implementation("net.kyori:text-adapter-bukkit:3.0.3") implementation("net.kyori:text-adapter-bukkit:3.0.3")
compile("com.github.MilkBowl:VaultAPI:1.7") { compile("com.github.MilkBowl:VaultAPI:1.7") {
exclude(module: "bukkit") exclude(module: "bukkit")
} }
implementation("me.clip:placeholderapi:2.10.4") implementation("me.clip:placeholderapi:2.10.6")
implementation("net.luckperms:api:5.1")
implementation("net.ess3:EssentialsX:2.17.2")
implementation("net.alpenblock:BungeePerms:4.0-dev-106")
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false } compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8
@ -87,10 +96,14 @@ shadowJar {
include(dependency("io.papermc:paperlib:1.0.2")) include(dependency("io.papermc:paperlib:1.0.2"))
include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("net.kyori:text-adapter-bukkit:3.0.3"))
include(dependency("org.bstats:bstats-bukkit:1.7")) include(dependency("org.bstats:bstats-bukkit:1.7"))
include(dependency("org.khelekore:prtree:1.7.0-SNAPSHOT"))
include(dependency("com.sk89q:squirrelid:1.0.0-SNAPSHOT"))
} }
relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate('net.kyori.text', 'com.plotsquared.formatting.text')
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
relocate("org.bstats", "com.plotsquared.metrics") relocate("org.bstats", "com.plotsquared.metrics")
relocate('com.sk89q.squirrelid', 'com.plotsquared.squirrelid')
relocate('org.khelekore.prtree', 'com.plotsquared.prtree')
archiveFileName = "${project.name}-${parent.version}.jar" archiveFileName = "${project.name}-${parent.version}.jar"
destinationDirectory = file "../target" destinationDirectory = file "../target"
} }

View File

@ -9,7 +9,7 @@
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20190722</version> <version>20200518</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -21,20 +21,26 @@
<dependency> <dependency>
<groupId>com.plotsquared</groupId> <groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Core</artifactId> <artifactId>PlotSquared-Core</artifactId>
<version>5.11.2</version> <version>5.12.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.destroystokyo.paper</groupId> <groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version> <version>1.16.1-R0.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sk89q.worldedit</groupId> <groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId> <artifactId>worldedit-bukkit</artifactId>
<version>7.0.1</version> <version>7.1.0</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>bukkit</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.papermc</groupId> <groupId>io.papermc</groupId>
@ -59,6 +65,24 @@
<artifactId>Core</artifactId> <artifactId>Core</artifactId>
<version>0.6.0-SNAPSHOT</version> <version>0.6.0-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>squirrelid</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sk89q.worldedit</groupId> <groupId>com.sk89q.worldedit</groupId>
@ -113,7 +137,7 @@
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version> <version>1.16.1-R0.1-SNAPSHOT</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -125,7 +149,25 @@
<dependency> <dependency>
<groupId>me.clip</groupId> <groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>
<version>2.10.4</version> <version>2.10.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.17.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.alpenblock</groupId>
<artifactId>BungeePerms</artifactId>
<version>4.0-dev-106</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -25,7 +25,6 @@
*/ */
package com.plotsquared.bukkit; package com.plotsquared.bukkit;
import com.plotsquared.bukkit.command.DebugUUID;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.command.MainCommand; import com.plotsquared.core.command.MainCommand;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
@ -46,10 +45,6 @@ import java.util.List;
public class BukkitCommand implements CommandExecutor, TabCompleter { public class BukkitCommand implements CommandExecutor, TabCompleter {
public BukkitCommand() {
new DebugUUID();
}
@Override @Override
public boolean onCommand(CommandSender commandSender, Command command, String commandLabel, public boolean onCommand(CommandSender commandSender, Command command, String commandLabel,
String[] args) { String[] args) {
@ -83,6 +78,6 @@ public class BukkitCommand implements CommandExecutor, TabCompleter {
for (com.plotsquared.core.command.Command o : objects) { for (com.plotsquared.core.command.Command o : objects) {
result.add(o.toString()); result.add(o.toString());
} }
return result.isEmpty() ? null : result; return result;
} }
} }

View File

@ -38,23 +38,27 @@ import com.plotsquared.bukkit.managers.HyperverseWorldManager;
import com.plotsquared.bukkit.managers.MultiverseWorldManager; import com.plotsquared.bukkit.managers.MultiverseWorldManager;
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter; import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
import com.plotsquared.bukkit.placeholder.Placeholders; import com.plotsquared.bukkit.placeholder.Placeholders;
import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.queue.BukkitLocalQueue; import com.plotsquared.bukkit.queue.BukkitLocalQueue;
import com.plotsquared.bukkit.schematic.BukkitSchematicHandler; import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChatManager; import com.plotsquared.bukkit.util.BukkitChatManager;
import com.plotsquared.bukkit.util.BukkitChunkManager; import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler; import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitPermHandler;
import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitTaskManager; import com.plotsquared.bukkit.util.BukkitTaskManager;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.SetGenCB; import com.plotsquared.bukkit.util.SetGenCB;
import com.plotsquared.bukkit.util.UpdateUtility; import com.plotsquared.bukkit.util.UpdateUtility;
import com.plotsquared.bukkit.util.uuid.DefaultUUIDWrapper; import com.plotsquared.bukkit.uuid.BungeePermsUUIDService;
import com.plotsquared.bukkit.util.uuid.FileUUIDHandler; import com.plotsquared.bukkit.uuid.EssentialsUUIDService;
import com.plotsquared.bukkit.util.uuid.LowerOfflineUUIDWrapper; import com.plotsquared.bukkit.uuid.LuckPermsUUIDService;
import com.plotsquared.bukkit.util.uuid.OfflineUUIDWrapper; import com.plotsquared.bukkit.uuid.OfflinePlayerUUIDService;
import com.plotsquared.bukkit.util.uuid.SQLUUIDHandler; import com.plotsquared.bukkit.uuid.PaperUUIDService;
import com.plotsquared.bukkit.uuid.SQLiteUUIDService;
import com.plotsquared.bukkit.uuid.SquirrelIdUUIDService;
import com.plotsquared.core.IPlotMain; import com.plotsquared.core.IPlotMain;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.backup.BackupManager;
@ -65,6 +69,7 @@ import com.plotsquared.core.configuration.ChatFormatter;
import com.plotsquared.core.configuration.ConfigurationNode; import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.generator.GeneratorWrapper; import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.generator.HybridGen; import com.plotsquared.core.generator.HybridGen;
import com.plotsquared.core.generator.HybridUtils; import com.plotsquared.core.generator.HybridUtils;
@ -77,19 +82,22 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType; import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.plot.message.PlainChatManager; import com.plotsquared.core.plot.message.PlainChatManager;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotArea; import com.plotsquared.core.plot.world.SinglePlotArea;
import com.plotsquared.core.plot.world.SinglePlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotAreaManager;
import com.plotsquared.core.queue.QueueProvider; import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.setup.PlotAreaBuilder;
import com.plotsquared.core.setup.SettingsNodesWrapper;
import com.plotsquared.core.util.ChatManager; import com.plotsquared.core.util.ChatManager;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.ConsoleColors; import com.plotsquared.core.util.ConsoleColors;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager; import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
import com.plotsquared.core.util.ReflectionUtils; import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
@ -98,9 +106,9 @@ import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler; import com.plotsquared.core.uuid.CacheUUIDService;
import com.plotsquared.core.util.uuid.UUIDHandlerImplementation; import com.plotsquared.core.uuid.UUIDPipeline;
import com.plotsquared.core.util.uuid.UUIDWrapper; import com.plotsquared.core.uuid.offline.OfflineModeUUIDService;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
@ -117,6 +125,7 @@ import org.bukkit.World;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -134,17 +143,24 @@ import java.util.AbstractMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import static com.plotsquared.core.util.PremiumVerification.getDownloadID; import static com.plotsquared.core.util.PremiumVerification.getDownloadID;
import static com.plotsquared.core.util.PremiumVerification.getResourceID; import static com.plotsquared.core.util.PremiumVerification.getResourceID;
import static com.plotsquared.core.util.PremiumVerification.getUserID; import static com.plotsquared.core.util.PremiumVerification.getUserID;
import static com.plotsquared.core.util.ReflectionUtils.getRefClass; import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain { public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<Player> {
private static final int BSTATS_ID = 1404; private static final int BSTATS_ID = 1404;
@Getter private static WorldEdit worldEdit; @Getter private static WorldEdit worldEdit;
@ -163,7 +179,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
private boolean methodUnloadSetup = false; private boolean methodUnloadSetup = false;
private boolean metricsStarted; private boolean metricsStarted;
@Getter private BackupManager backupManager; @Getter private BackupManager backupManager;
@Getter private PlatformWorldManager worldManager; @Getter private PlatformWorldManager<World> worldManager;
private final BukkitPlayerManager playerManager = new BukkitPlayerManager();
private EconHandler econ;
private PermHandler perm;
@Override public int[] getServerVersion() { @Override public int[] getServerVersion() {
if (this.version == null) { if (this.version == null) {
@ -221,6 +240,122 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
PlotSquared.log(Captions.PREFIX + "&6Couldn't verify purchase :("); PlotSquared.log(Captions.PREFIX + "&6Couldn't verify purchase :(");
} }
final UUIDPipeline impromptuPipeline = PlotSquared.get().getImpromptuUUIDPipeline();
final UUIDPipeline backgroundPipeline = PlotSquared.get().getBackgroundUUIDPipeline();
// Services are accessed in order
final CacheUUIDService cacheUUIDService =
new CacheUUIDService(Settings.UUID.UUID_CACHE_SIZE);
impromptuPipeline.registerService(cacheUUIDService);
backgroundPipeline.registerService(cacheUUIDService);
impromptuPipeline.registerConsumer(cacheUUIDService);
backgroundPipeline.registerConsumer(cacheUUIDService);
// Now, if the server is in offline mode we can only use profiles and direct UUID
// access, and so we skip the player profile stuff as well as SquirrelID (Mojang lookups)
if (Settings.UUID.OFFLINE) {
final OfflineModeUUIDService offlineModeUUIDService = new OfflineModeUUIDService();
impromptuPipeline.registerService(offlineModeUUIDService);
backgroundPipeline.registerService(offlineModeUUIDService);
PlotSquared.log(Captions.PREFIX + "(UUID) Using the offline mode UUID service");
}
final OfflinePlayerUUIDService offlinePlayerUUIDService = new OfflinePlayerUUIDService();
impromptuPipeline.registerService(offlinePlayerUUIDService);
backgroundPipeline.registerService(offlinePlayerUUIDService);
final SQLiteUUIDService sqLiteUUIDService = new SQLiteUUIDService("user_cache.db");
final SQLiteUUIDService legacyUUIDService;
if (Settings.UUID.LEGACY_DATABASE_SUPPORT && MainUtil
.getFile(PlotSquared.get().IMP.getDirectory(), "usercache.db").exists()) {
legacyUUIDService = new SQLiteUUIDService("usercache.db");
} else {
legacyUUIDService = null;
}
final LuckPermsUUIDService luckPermsUUIDService;
if (Bukkit.getPluginManager().getPlugin("LuckPerms") != null) {
luckPermsUUIDService = new LuckPermsUUIDService();
PlotSquared
.log(Captions.PREFIX + "(UUID) Using LuckPerms as a complementary UUID service");
} else {
luckPermsUUIDService = null;
}
final BungeePermsUUIDService bungeePermsUUIDService;
if (Bukkit.getPluginManager().getPlugin("BungeePerms") != null) {
bungeePermsUUIDService = new BungeePermsUUIDService();
PlotSquared
.log(Captions.PREFIX + "(UUID) Using BungeePerms as a complementary UUID service");
} else {
bungeePermsUUIDService = null;
}
final EssentialsUUIDService essentialsUUIDService;
if (Bukkit.getPluginManager().getPlugin("Essentials") != null) {
essentialsUUIDService = new EssentialsUUIDService();
PlotSquared
.log(Captions.PREFIX + "(UUID) Using Essentials as a complementary UUID service");
} else {
essentialsUUIDService = null;
}
if (!Settings.UUID.OFFLINE) {
// If running Paper we'll also try to use their profiles
if (PaperLib.isPaper()) {
final PaperUUIDService paperUUIDService = new PaperUUIDService();
impromptuPipeline.registerService(paperUUIDService);
backgroundPipeline.registerService(paperUUIDService);
PlotSquared
.log(Captions.PREFIX + "(UUID) Using Paper as a complementary UUID service");
}
impromptuPipeline.registerService(sqLiteUUIDService);
backgroundPipeline.registerService(sqLiteUUIDService);
impromptuPipeline.registerConsumer(sqLiteUUIDService);
backgroundPipeline.registerConsumer(sqLiteUUIDService);
if (legacyUUIDService != null) {
impromptuPipeline.registerService(legacyUUIDService);
backgroundPipeline.registerService(legacyUUIDService);
}
// Plugin providers
if (luckPermsUUIDService != null) {
impromptuPipeline.registerService(luckPermsUUIDService);
backgroundPipeline.registerService(luckPermsUUIDService);
}
if (bungeePermsUUIDService != null) {
impromptuPipeline.registerService(bungeePermsUUIDService);
backgroundPipeline.registerService(bungeePermsUUIDService);
}
if (essentialsUUIDService != null) {
impromptuPipeline.registerService(essentialsUUIDService);
backgroundPipeline.registerService(essentialsUUIDService);
}
final SquirrelIdUUIDService impromptuMojangService =
new SquirrelIdUUIDService(Settings.UUID.IMPROMPTU_LIMIT);
impromptuPipeline.registerService(impromptuMojangService);
final SquirrelIdUUIDService backgroundMojangService =
new SquirrelIdUUIDService(Settings.UUID.BACKGROUND_LIMIT);
backgroundPipeline.registerService(backgroundMojangService);
} else {
impromptuPipeline.registerService(sqLiteUUIDService);
backgroundPipeline.registerService(sqLiteUUIDService);
impromptuPipeline.registerConsumer(sqLiteUUIDService);
backgroundPipeline.registerConsumer(sqLiteUUIDService);
if (legacyUUIDService != null) {
impromptuPipeline.registerService(legacyUUIDService);
backgroundPipeline.registerService(legacyUUIDService);
}
}
impromptuPipeline.storeImmediately("*", DBFunc.EVERYONE);
this.startUuidCatching(sqLiteUUIDService, cacheUUIDService);
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new Placeholders().register(); new Placeholders().register();
if (Settings.Enabled_Components.EXTERNAL_PLACEHOLDERS) { if (Settings.Enabled_Components.EXTERNAL_PLACEHOLDERS) {
@ -259,8 +394,22 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
this.worldManager = new BukkitWorldManager(); this.worldManager = new BukkitWorldManager();
} }
PlotSquared.log(Captions.PREFIX.getTranslated() + "Using platform world manager: " + PlotSquared.log(
this.worldManager.getName()); Captions.PREFIX.getTranslated() + "Using platform world manager: " + this.worldManager
.getName());
// Clean up potential memory leak
Bukkit.getScheduler().runTaskTimer(this, () -> {
try {
for (final PlotPlayer<? extends Player> player : this.getPlayerManager().getPlayers()) {
if (player.getPlatformPlayer() == null || !player.getPlatformPlayer().isOnline()) {
this.getPlayerManager().removePlayer(player);
}
}
} catch (final Exception e) {
getLogger().warning("Failed to clean up players: " + e.getMessage());
}
}, 100L, 100L);
} }
private void unload() { private void unload() {
@ -342,6 +491,77 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
} }
private void startUuidCatching(@NotNull final SQLiteUUIDService sqLiteUUIDService,
@NotNull final CacheUUIDService cacheUUIDService) {
// Load all uuids into a big chunky boi queue
final Queue<UUID> uuidQueue = new LinkedBlockingQueue<>();
PlotSquared.get().forEachPlotRaw(plot -> {
final Set<UUID> uuids = new HashSet<>();
uuids.add(plot.getOwnerAbs());
uuids.addAll(plot.getMembers());
uuids.addAll(plot.getTrusted());
uuids.addAll(plot.getDenied());
for (final UUID uuid : uuids) {
if (!uuidQueue.contains(uuid)) {
uuidQueue.add(uuid);
}
}
});
PlotSquared.log(Captions.PREFIX.getTranslated() + "(UUID) " + uuidQueue.size()
+ " UUIDs will be cached.");
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
// Begin by reading all the SQLite cache at once
cacheUUIDService.accept(sqLiteUUIDService.getAll());
// Now fetch names for all known UUIDs
final int totalSize = uuidQueue.size();
int read = 0;
PlotSquared.log(Captions.PREFIX.getTranslated()
+ "(UUID) PlotSquared will fetch UUIDs in groups of "
+ Settings.UUID.BACKGROUND_LIMIT);
final List<UUID> uuidList = new ArrayList<>(Settings.UUID.BACKGROUND_LIMIT);
// Used to indicate that the second retrieval has been attempted
boolean secondRun = false;
while (!uuidQueue.isEmpty() || !uuidList.isEmpty()) {
if (!uuidList.isEmpty() && secondRun) {
PlotSquared.log("Giving up on last batch. Fetching new batch instead.");
uuidList.clear();
}
if (uuidList.isEmpty()) {
// Retrieve the secondRun variable to indicate that we're retrieving a
// fresh batch
secondRun = false;
// Populate the request list
for (int i = 0;
i < Settings.UUID.BACKGROUND_LIMIT && !uuidQueue.isEmpty(); i++) {
uuidList.add(uuidQueue.poll());
read++;
}
} else {
// If the list isn't empty then this is a second run for
// an old batch, so we re-use the patch
secondRun = true;
}
try {
PlotSquared.get().getBackgroundUUIDPipeline().getNames(uuidList).get();
// Clear the list if we successfully index all the names
uuidList.clear();
// Print progress
final double percentage = ((double) read / (double) totalSize) * 100.0D;
PlotSquared.log(Captions.PREFIX.getTranslated() + String
.format("(UUID) PlotSquared has cached %.1f%% of UUIDs", percentage));
} catch (final InterruptedException | ExecutionException e) {
PlotSquared.log("Failed to retrieve that batch. Will try again.");
e.printStackTrace();
}
}
PlotSquared
.log(Captions.PREFIX.getTranslated() + "(UUID) PlotSquared has cached all UUIDs");
}, 10, TimeUnit.SECONDS);
}
@Override public void onDisable() { @Override public void onDisable() {
PlotSquared.get().disable(); PlotSquared.get().disable();
Bukkit.getScheduler().cancelTasks(this); Bukkit.getScheduler().cancelTasks(this);
@ -411,46 +631,46 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
Iterator<Entity> iterator = entities.iterator(); Iterator<Entity> iterator = entities.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = iterator.next(); Entity entity = iterator.next();
switch (entity.getType()) { switch (entity.getType().toString()) {
case EGG: case "EGG":
case FISHING_HOOK: case "FISHING_HOOK":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case LEASH_HITCH: case "LEASH_HITCH":
case FIREWORK: case "FIREWORK":
case LIGHTNING: case "LIGHTNING":
case WITHER_SKULL: case "WITHER_SKULL":
case UNKNOWN: case "UNKNOWN":
case PLAYER: case "PLAYER":
// non moving / unmovable // non moving / unmovable
continue; continue;
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case SPLASH_POTION: case "SPLASH_POTION":
case SNOWBALL: case "SNOWBALL":
case SHULKER_BULLET: case "SHULKER_BULLET":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case ENDER_PEARL: case "ENDER_PEARL":
case ARROW: case "ARROW":
case LLAMA_SPIT: case "LLAMA_SPIT":
case TRIDENT: case "TRIDENT":
// managed elsewhere | projectile // managed elsewhere | projectile
continue; continue;
case ITEM_FRAME: case "ITEM_FRAME":
case PAINTING: case "PAINTING":
// Not vehicles // Not vehicles
continue; continue;
case ARMOR_STAND: case "ARMOR_STAND":
// Temporarily classify as vehicle // Temporarily classify as vehicle
case MINECART: case "MINECART":
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_FURNACE: case "MINECART_FURNACE":
case MINECART_HOPPER: case "MINECART_HOPPER":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case MINECART_TNT: case "MINECART_TNT":
case BOAT: case "BOAT":
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
com.plotsquared.core.location.Location location = com.plotsquared.core.location.Location location =
BukkitUtil.getLocation(entity.getLocation()); BukkitUtil.getLocation(entity.getLocation());
@ -479,10 +699,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
} }
continue; continue;
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case FIREBALL: case "FIREBALL":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case DROPPED_ITEM: case "DROPPED_ITEM":
if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea
.getOwnedPlotAbs(BukkitUtil.getLocation(entity.getLocation())) .getOwnedPlotAbs(BukkitUtil.getLocation(entity.getLocation()))
== null) { == null) {
@ -490,11 +710,11 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
// dropped item // dropped item
continue; continue;
case PRIMED_TNT: case "PRIMED_TNT":
case FALLING_BLOCK: case "FALLING_BLOCK":
// managed elsewhere // managed elsewhere
continue; continue;
case SHULKER: case "SHULKER":
if (Settings.Enabled_Components.KILL_ROAD_MOBS) { if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
LivingEntity livingEntity = (LivingEntity) entity; LivingEntity livingEntity = (LivingEntity) entity;
List<MetadataValue> meta = entity.getMetadata("shulkerPlot"); List<MetadataValue> meta = entity.getMetadata("shulkerPlot");
@ -542,71 +762,76 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
} }
continue; continue;
case LLAMA: case "ZOMBIFIED_PIGLIN":
case DONKEY: case "LLAMA":
case MULE: case "DONKEY":
case ZOMBIE_HORSE: case "MULE":
case SKELETON_HORSE: case "ZOMBIE_HORSE":
case HUSK: case "SKELETON_HORSE":
case ELDER_GUARDIAN: case "HUSK":
case WITHER_SKELETON: case "ELDER_GUARDIAN":
case STRAY: case "WITHER_SKELETON":
case ZOMBIE_VILLAGER: case "STRAY":
case EVOKER: case "ZOMBIE_VILLAGER":
case EVOKER_FANGS: case "EVOKER":
case VEX: case "EVOKER_FANGS":
case VINDICATOR: case "VEX":
case POLAR_BEAR: case "VINDICATOR":
case BAT: case "POLAR_BEAR":
case BLAZE: case "BAT":
case CAVE_SPIDER: case "BLAZE":
case CHICKEN: case "CAVE_SPIDER":
case COW: case "CHICKEN":
case CREEPER: case "COW":
case ENDERMAN: case "CREEPER":
case ENDERMITE: case "ENDERMAN":
case ENDER_DRAGON: case "ENDERMITE":
case GHAST: case "ENDER_DRAGON":
case GIANT: case "GHAST":
case GUARDIAN: case "GIANT":
case HORSE: case "GUARDIAN":
case IRON_GOLEM: case "HORSE":
case MAGMA_CUBE: case "IRON_GOLEM":
case MUSHROOM_COW: case "MAGMA_CUBE":
case OCELOT: case "MUSHROOM_COW":
case PIG: case "OCELOT":
case PIG_ZOMBIE: case "PIG":
case RABBIT: case "PIG_ZOMBIE":
case SHEEP: case "RABBIT":
case SILVERFISH: case "SHEEP":
case SKELETON: case "SILVERFISH":
case SLIME: case "SKELETON":
case SNOWMAN: case "SLIME":
case SPIDER: case "SNOWMAN":
case SQUID: case "SPIDER":
case VILLAGER: case "SQUID":
case WITCH: case "VILLAGER":
case WITHER: case "WITCH":
case WOLF: case "WITHER":
case ZOMBIE: case "WOLF":
case PARROT: case "ZOMBIE":
case SALMON: case "PARROT":
case DOLPHIN: case "SALMON":
case TROPICAL_FISH: case "DOLPHIN":
case DROWNED: case "TROPICAL_FISH":
case COD: case "DROWNED":
case TURTLE: case "COD":
case PUFFERFISH: case "TURTLE":
case PHANTOM: case "PUFFERFISH":
case ILLUSIONER: case "PHANTOM":
case CAT: case "ILLUSIONER":
case PANDA: case "CAT":
case FOX: case "PANDA":
case PILLAGER: case "FOX":
case TRADER_LLAMA: case "PILLAGER":
case WANDERING_TRADER: case "TRADER_LLAMA":
case RAVAGER: case "WANDERING_TRADER":
//case BEE: case "RAVAGER":
case "BEE":
case "HOGLIN":
case "PIGLIN":
case "ZOGLIN":
break;
default: { default: {
if (Settings.Enabled_Components.KILL_ROAD_MOBS) { if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
Location location = entity.getLocation(); Location location = entity.getLocation();
@ -687,8 +912,16 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
@Override public EconHandler getEconomyHandler() { @Override public EconHandler getEconomyHandler() {
if (econ != null) {
if (econ.init() /* is inited */) {
return econ;
} else {
return null;
}
}
try { try {
BukkitEconHandler econ = new BukkitEconHandler(); econ = new BukkitEconHandler();
if (econ.init()) { if (econ.init()) {
return econ; return econ;
} }
@ -698,6 +931,26 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return null; return null;
} }
@Override public PermHandler getPermissionHandler() {
if (perm != null) {
if (perm.init() /* is inited */) {
return perm;
} else {
return null;
}
}
try {
perm = new BukkitPermHandler();
if (perm.init()) {
return perm;
}
} catch (Throwable ignored) {
PlotSquared.debug("No permissions detected!");
}
return null;
}
@Override public QueueProvider initBlockQueue() { @Override public QueueProvider initBlockQueue() {
//TODO Figure out why this code is still here yet isn't being called anywhere. //TODO Figure out why this code is still here yet isn't being called anywhere.
// try { // try {
@ -715,8 +968,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return new BukkitUtil(); return new BukkitUtil();
} }
@Override @Nullable @Override @Nullable public GeneratorWrapper<?> getGenerator(@NonNull final String world,
public GeneratorWrapper<?> getGenerator(@NonNull final String world,
@Nullable final String name) { @Nullable final String name) {
if (name == null) { if (name == null) {
return null; return null;
@ -767,7 +1019,9 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
metrics.addCustomChart(new Metrics.SimplePie("premium", metrics.addCustomChart(new Metrics.SimplePie("premium",
() -> PremiumVerification.isPremium() ? "Premium" : "Non-Premium")); () -> PremiumVerification.isPremium() ? "Premium" : "Non-Premium"));
metrics.addCustomChart(new Metrics.SimplePie("worldedit_implementation", metrics.addCustomChart(new Metrics.SimplePie("worldedit_implementation",
() -> Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null ? "FastAsyncWorldEdit" : "WorldEdit")); () -> Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null ?
"FastAsyncWorldEdit" :
"WorldEdit"));
} }
@Override public ChunkManager initChunkManager() { @Override public ChunkManager initChunkManager() {
@ -779,7 +1033,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
@Override public void unregister(@NonNull final PlotPlayer player) { @Override public void unregister(@NonNull final PlotPlayer player) {
BukkitUtil.removePlayer(player.getName()); BukkitUtil.removePlayer(player.getUUID());
} }
@Override public void registerChunkProcessor() { @Override public void registerChunkProcessor() {
@ -798,39 +1052,6 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return new BukkitInventoryUtil(); return new BukkitInventoryUtil();
} }
@Override public UUIDHandlerImplementation initUUIDHandler() {
final UUIDWrapper wrapper;
if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE) {
wrapper = new LowerOfflineUUIDWrapper();
} else {
wrapper = new OfflineUUIDWrapper();
}
Settings.UUID.OFFLINE = true;
} else {
wrapper = new DefaultUUIDWrapper();
Settings.UUID.OFFLINE = false;
}
if (!Bukkit.getVersion().contains("git-Spigot")) {
if (wrapper instanceof DefaultUUIDWrapper
|| wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
Settings.UUID.NATIVE_UUID_PROVIDER = true;
}
}
if (Settings.UUID.OFFLINE) {
PlotSquared.log(Captions.PREFIX + "&6" + getPluginName()
+ " is using Offline Mode UUIDs either because of user preference, or because you are using an old version of "
+ "Bukkit");
} else {
PlotSquared.log(Captions.PREFIX + "&6" + getPluginName() + " is using online UUIDs");
}
if (Settings.UUID.USE_SQLUUIDHANDLER) {
return new SQLUUIDHandler(wrapper);
} else {
return new FileUUIDHandler(wrapper);
}
}
@Override public void setGenerator(@NonNull final String worldName) { @Override public void setGenerator(@NonNull final String worldName) {
World world = BukkitUtil.getWorld(worldName); World world = BukkitUtil.getWorld(worldName);
if (world == null) { if (world == null) {
@ -838,14 +1059,13 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
ConfigurationSection worldConfig = ConfigurationSection worldConfig =
PlotSquared.get().worlds.getConfigurationSection("worlds." + worldName); PlotSquared.get().worlds.getConfigurationSection("worlds." + worldName);
String manager = worldConfig.getString("generator.plugin", getPluginName()); String manager = worldConfig.getString("generator.plugin", getPluginName());
SetupObject setup = new SetupObject(); PlotAreaBuilder builder = new PlotAreaBuilder().plotManager(manager)
setup.plotManager = manager; .generatorName(worldConfig.getString("generator.init", manager))
setup.setupGenerator = worldConfig.getString("generator.init", manager); .plotAreaType(MainUtil.getType(worldConfig))
setup.type = MainUtil.getType(worldConfig); .terrainType(MainUtil.getTerrain(worldConfig))
setup.terrain = MainUtil.getTerrain(worldConfig); .settingsNodesWrapper(new SettingsNodesWrapper(new ConfigurationNode[0], null))
setup.step = new ConfigurationNode[0]; .worldName(worldName);
setup.world = worldName; SetupUtils.manager.setupWorld(builder);
SetupUtils.manager.setupWorld(setup);
world = Bukkit.getWorld(worldName); world = Bukkit.getWorld(worldName);
} else { } else {
try { try {
@ -873,7 +1093,22 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return new BukkitSchematicHandler(); return new BukkitSchematicHandler();
} }
@Override @Nullable public PlotPlayer wrapPlayer(final Object player) { /**
* Attempt to retrieve a {@link PlotPlayer} from a player identifier.
* This method accepts:
* - {@link Player} objects,
* - {@link OfflinePlayer} objects,
* - {@link String} usernames for online players, and
* - {@link UUID} UUIDs for online players
* <p>
* In the case of offline players, a fake {@link Player} instance will be created.
* This is a rather expensive operation, and should be avoided if possible.
*
* @param player The player to convert to a PlotPlayer
* @return The plot player instance that corresponds to the identifier, or null
* if no such player object could be created
*/
@Override @Nullable public PlotPlayer<Player> wrapPlayer(final Object player) {
if (player instanceof Player) { if (player instanceof Player) {
return BukkitUtil.getPlayer((Player) player); return BukkitUtil.getPlayer((Player) player);
} }
@ -881,10 +1116,12 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return BukkitUtil.getPlayer((OfflinePlayer) player); return BukkitUtil.getPlayer((OfflinePlayer) player);
} }
if (player instanceof String) { if (player instanceof String) {
return UUIDHandler.getPlayer((String) player); return (PlotPlayer<Player>) PlotSquared.imp().getPlayerManager()
.getPlayerIfExists((String) player);
} }
if (player instanceof UUID) { if (player instanceof UUID) {
return UUIDHandler.getPlayer((UUID) player); return (PlotPlayer<Player>) PlotSquared.imp().getPlayerManager()
.getPlayerIfExists((UUID) player);
} }
return null; return null;
} }
@ -902,8 +1139,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
} }
@Override @Override public GeneratorWrapper<?> wrapPlotGenerator(@Nullable final String world,
public GeneratorWrapper<?> wrapPlotGenerator(@Nullable final String world,
@NonNull final IndependentPlotGenerator generator) { @NonNull final IndependentPlotGenerator generator) {
return new BukkitPlotGenerator(world, generator); return new BukkitPlotGenerator(world, generator);
} }
@ -925,4 +1161,9 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return wePlugin.wrapCommandSender(console); return wePlugin.wrapCommandSender(console);
} }
@Override @NotNull
public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() {
return this.playerManager;
}
} }

View File

@ -1,323 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.command;
import com.google.common.collect.Sets;
import com.plotsquared.bukkit.util.uuid.DatFileFilter;
import com.plotsquared.bukkit.util.uuid.DefaultUUIDWrapper;
import com.plotsquared.bukkit.util.uuid.LowerOfflineUUIDWrapper;
import com.plotsquared.bukkit.util.uuid.OfflineUUIDWrapper;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.Argument;
import com.plotsquared.core.command.CommandCategory;
import com.plotsquared.core.command.CommandDeclaration;
import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.command.SubCommand;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
@CommandDeclaration(command = "uuidconvert",
permission = "plots.admin",
description = "Debug UUID conversion",
usage = "/plot uuidconvert <lower|offline|online>",
requiredType = RequiredType.CONSOLE,
category = CommandCategory.DEBUG)
public class DebugUUID extends SubCommand {
public DebugUUID() {
super(Argument.String);
}
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
final UUIDWrapper currentUUIDWrapper = UUIDHandler.getUUIDWrapper();
final UUIDWrapper newWrapper;
switch (args[0].toLowerCase()) {
case "lower":
newWrapper = new LowerOfflineUUIDWrapper();
break;
case "offline":
newWrapper = new OfflineUUIDWrapper();
break;
case "online":
newWrapper = new DefaultUUIDWrapper();
break;
default:
try {
Class<?> clazz = Class.forName(args[0]);
newWrapper = (UUIDWrapper) clazz.newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException ignored) {
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX,
"/plot uuidconvert <lower|offline|online>");
return false;
}
}
if (args.length != 2 || !"-o".equals(args[1])) {
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX,
"/plot uuidconvert " + args[0] + " -o");
MainUtil.sendMessage(player, "&cBe aware of the following!");
MainUtil.sendMessage(player,
"&8 - &cUse the database command or another method to backup your plots beforehand");
MainUtil.sendMessage(player,
"&8 - &cIf the process is interrupted, all plots could be deleted");
MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted");
MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion");
MainUtil
.sendMessage(player, "&cTO REITERATE: BACK UP YOUR DATABASE BEFORE USING THIS!!!");
MainUtil.sendMessage(player,
"&7Retype the command with the override parameter when ready :)");
return false;
}
if (currentUUIDWrapper.getClass().getCanonicalName()
.equals(newWrapper.getClass().getCanonicalName())) {
MainUtil.sendMessage(player, "&cUUID mode already in use!");
return false;
}
MainUtil.sendMessage(player, "&6Beginning UUID mode conversion");
MainUtil.sendMessage(player, "&7 - Disconnecting players");
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
entry.getValue()
.kick("UUID conversion has been initiated. You may reconnect when finished.");
}
MainUtil.sendMessage(player, "&7 - Initializing map");
final HashMap<UUID, UUID> uCMap = new HashMap<>();
final HashMap<UUID, UUID> uCReverse = new HashMap<>();
MainUtil.sendMessage(player, "&7 - Collecting playerdata");
HashSet<String> worlds = Sets.newHashSet(WorldUtil.IMP.getMainWorld(), "world");
HashSet<UUID> uuids = new HashSet<>();
HashSet<String> names = new HashSet<>();
for (String worldName : worlds) {
File playerDataFolder = new File(worldName + File.separator + "playerdata");
String[] dat = playerDataFolder.list(new DatFileFilter());
if (dat != null) {
for (String current : dat) {
String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (Exception ignored) {
MainUtil.sendMessage(player,
Captions.PREFIX + "Invalid playerdata: " + current);
}
}
}
File playersFolder = new File(worldName + File.separator + "players");
dat = playersFolder.list(new DatFileFilter());
if (dat != null) {
for (String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
}
}
MainUtil.sendMessage(player, "&7 - Populating map");
UUID uuid2;
UUIDWrapper wrapper = new DefaultUUIDWrapper();
for (UUID uuid : uuids) {
try {
OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid);
uuid = currentUUIDWrapper.getUUID(op);
uuid2 = newWrapper.getUUID(op);
if (!uuid.equals(uuid2) && !uCMap.containsKey(uuid) && !uCReverse
.containsKey(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
} catch (Throwable ignored) {
MainUtil.sendMessage(player,
Captions.PREFIX + "&6Invalid playerdata: " + uuid.toString() + ".dat");
}
}
for (String name : names) {
UUID uuid = currentUUIDWrapper.getUUID(name);
uuid2 = newWrapper.getUUID(name);
if (!uuid.equals(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
}
if (uCMap.isEmpty()) {
MainUtil.sendMessage(player, "&c - Error! Attempting to repopulate");
for (OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) {
if (op.getLastPlayed() != 0) {
// String name = op.getPluginName();
// StringWrapper wrap = new StringWrapper(name);
UUID uuid = currentUUIDWrapper.getUUID(op);
uuid2 = newWrapper.getUUID(op);
if (!uuid.equals(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
}
}
if (uCMap.isEmpty()) {
MainUtil.sendMessage(player, "&cError. Failed to collect UUIDs!");
return false;
} else {
MainUtil.sendMessage(player, "&a - Successfully repopulated");
}
}
MainUtil.sendMessage(player, "&7 - Replacing cache");
TaskManager.runTaskAsync(() -> {
for (Entry<UUID, UUID> entry : uCMap.entrySet()) {
String name = UUIDHandler.getName(entry.getKey());
if (name != null) {
UUIDHandler.add(new StringWrapper(name), entry.getValue());
}
}
MainUtil.sendMessage(player, "&7 - Scanning for applicable files (uuids.txt)");
File file = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt");
if (file.exists()) {
try {
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
for (String line : lines) {
try {
line = line.trim();
if (line.isEmpty()) {
continue;
}
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
String[] split = line.split("\\|");
String name = split[0];
if (name.isEmpty() || name.length() > 16 || !StringMan
.isAlphanumericUnd(name)) {
continue;
}
UUID old = currentUUIDWrapper.getUUID(name);
if (old == null) {
continue;
}
UUID now = newWrapper.getUUID(name);
UUIDHandler.add(new StringWrapper(name), now);
uCMap.put(old, now);
uCReverse.put(now, old);
} catch (Exception e2) {
e2.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
MainUtil.sendMessage(player, "&7 - Replacing wrapper");
UUIDHandler.setUUIDWrapper(newWrapper);
MainUtil.sendMessage(player, "&7 - Updating plot objects");
for (Plot plot : PlotSquared.get().getPlots()) {
UUID value = uCMap.get(plot.getOwnerAbs());
if (value != null) {
plot.setOwnerAbs(value);
}
plot.getTrusted().clear();
plot.getMembers().clear();
plot.getDenied().clear();
}
MainUtil.sendMessage(player, "&7 - Deleting database");
boolean result = DBFunc.deleteTables();
MainUtil.sendMessage(player, "&7 - Creating tables");
try {
DBFunc.createTables();
if (!result) {
MainUtil.sendMessage(player, "&cConversion failed! Attempting recovery");
for (Plot plot : PlotSquared.get().getPlots()) {
UUID value = uCReverse.get(plot.getOwnerAbs());
if (value != null) {
plot.setOwnerAbs(value);
}
}
DBFunc.createPlotsAndData(new ArrayList<>(PlotSquared.get().getPlots()),
() -> MainUtil.sendMessage(player, "&6Recovery was successful!"));
return;
}
} catch (Exception e) {
e.printStackTrace();
return;
}
if (newWrapper instanceof OfflineUUIDWrapper) {
PlotSquared.get().worlds.set("UUID.force-lowercase", false);
PlotSquared.get().worlds.set("UUID.offline", true);
} else if (newWrapper instanceof DefaultUUIDWrapper) {
PlotSquared.get().worlds.set("UUID.force-lowercase", false);
PlotSquared.get().worlds.set("UUID.offline", false);
}
try {
PlotSquared.get().worlds.save(PlotSquared.get().worldsFile);
} catch (IOException ignored) {
MainUtil.sendMessage(player,
"Could not save configuration. It will need to be manual set!");
}
MainUtil.sendMessage(player, "&7 - Populating tables");
TaskManager.runTaskAsync(() -> {
ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots());
DBFunc.createPlotsAndData(plots,
() -> MainUtil.sendMessage(player, "&aConversion complete!"));
});
MainUtil.sendMessage(player, "&aIt is now safe for players to join");
MainUtil.sendMessage(player,
"&cConversion is still in progress, you will be notified when it is complete");
});
return true;
}
}

View File

@ -103,51 +103,51 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (!entity.hasGravity()) { if (!entity.hasGravity()) {
this.noGravity = true; this.noGravity = true;
} }
switch (entity.getType()) { switch (entity.getType().toString()) {
case BOAT: case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
return; return;
case ARROW: case "ARROW":
case EGG: case "EGG":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case ENDER_PEARL: case "ENDER_PEARL":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case FALLING_BLOCK: case "FALLING_BLOCK":
case FIREBALL: case "FIREBALL":
case FIREWORK: case "FIREWORK":
case FISHING_HOOK: case "FISHING_HOOK":
case LEASH_HITCH: case "LEASH_HITCH":
case LIGHTNING: case "LIGHTNING":
case MINECART: case "MINECART":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case MINECART_TNT: case "MINECART_TNT":
case PLAYER: case "PLAYER":
case PRIMED_TNT: case "PRIMED_TNT":
case SLIME: case "SLIME":
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case SNOWBALL: case "SNOWBALL":
case MINECART_FURNACE: case "MINECART_FURNACE":
case SPLASH_POTION: case "SPLASH_POTION":
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case WITHER_SKULL: case "WITHER_SKULL":
case UNKNOWN: case "UNKNOWN":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case SHULKER_BULLET: case "SHULKER_BULLET":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case TRIDENT: case "TRIDENT":
case LLAMA_SPIT: case "LLAMA_SPIT":
// Do this stuff later // Do this stuff later
return; return;
// MISC // // MISC //
case DROPPED_ITEM: case "DROPPED_ITEM":
Item item = (Item) entity; Item item = (Item) entity;
this.stack = item.getItemStack(); this.stack = item.getItemStack();
return; return;
case ITEM_FRAME: case "ITEM_FRAME":
this.x = Math.floor(this.x); this.x = Math.floor(this.x);
this.y = Math.floor(this.y); this.y = Math.floor(this.y);
this.z = Math.floor(this.z); this.z = Math.floor(this.z);
@ -155,7 +155,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation()); this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
this.stack = itemFrame.getItem().clone(); this.stack = itemFrame.getItem().clone();
return; return;
case PAINTING: case "PAINTING":
this.x = Math.floor(this.x); this.x = Math.floor(this.x);
this.y = Math.floor(this.y); this.y = Math.floor(this.y);
this.z = Math.floor(this.z); this.z = Math.floor(this.z);
@ -170,18 +170,18 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return; return;
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_HOPPER: case "MINECART_HOPPER":
storeInventory((InventoryHolder) entity); storeInventory((InventoryHolder) entity);
return; return;
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case HORSE: case "HORSE":
case DONKEY: case "DONKEY":
case LLAMA: case "LLAMA":
case MULE: case "MULE":
case SKELETON_HORSE: case "SKELETON_HORSE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
this.horse = new HorseStats(); this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength(); this.horse.jump = horse.getJumpStrength();
@ -199,15 +199,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeInventory(horse); storeInventory(horse);
return; return;
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case WOLF: case "WOLF":
case OCELOT: case "OCELOT":
storeTameable((Tameable) entity); storeTameable((Tameable) entity);
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
// END TAMEABLE // // END TAMEABLE //
//todo fix sheep //todo fix sheep
case SHEEP: case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
@ -218,23 +218,23 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeAgeable(sheep); storeAgeable(sheep);
storeLiving(sheep); storeLiving(sheep);
return; return;
case VILLAGER: case "VILLAGER":
case CHICKEN: case "CHICKEN":
case COW: case "COW":
case MUSHROOM_COW: case "MUSHROOM_COW":
case PIG: case "PIG":
case TURTLE: case "TURTLE":
case POLAR_BEAR: case "POLAR_BEAR":
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case RABBIT: case "RABBIT":
this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
// END AGEABLE // // END AGEABLE //
case ARMOR_STAND: case "ARMOR_STAND":
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
this.inventory = this.inventory =
new ItemStack[] {stand.getItemInHand().clone(), stand.getHelmet().clone(), new ItemStack[] {stand.getItemInHand().clone(), stand.getHelmet().clone(),
@ -286,42 +286,45 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.stand.small = true; this.stand.small = true;
} }
return; return;
case ENDERMITE: case "ENDERMITE":
return; return;
case BAT: case "BAT":
if (((Bat) entity).isAwake()) { if (((Bat) entity).isAwake()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
return; return;
case ENDER_DRAGON: case "ENDER_DRAGON":
EnderDragon entity1 = (EnderDragon) entity; EnderDragon entity1 = (EnderDragon) entity;
this.dataByte = (byte) entity1.getPhase().ordinal(); this.dataByte = (byte) entity1.getPhase().ordinal();
return; return;
case SKELETON: case "SKELETON":
case WITHER_SKELETON: case "WITHER_SKELETON":
case GUARDIAN: case "GUARDIAN":
case ELDER_GUARDIAN: case "ELDER_GUARDIAN":
case GHAST: case "GHAST":
case MAGMA_CUBE: case "MAGMA_CUBE":
case SQUID: case "SQUID":
case PIG_ZOMBIE: case "PIG_ZOMBIE":
case ZOMBIE: case "HOGLIN":
case WITHER: case "ZOMBIFIED_PIGLIN":
case WITCH: case "PIGLIN":
case SPIDER: case "ZOMBIE":
case CAVE_SPIDER: case "WITHER":
case SILVERFISH: case "WITCH":
case GIANT: case "SPIDER":
case ENDERMAN: case "CAVE_SPIDER":
case CREEPER: case "SILVERFISH":
case BLAZE: case "GIANT":
case SHULKER: case "ENDERMAN":
case SNOWMAN: case "CREEPER":
case "BLAZE":
case "SHULKER":
case "SNOWMAN":
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case IRON_GOLEM: case "IRON_GOLEM":
if (((IronGolem) entity).isPlayerCreated()) { if (((IronGolem) entity).isPlayerCreated()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
@ -463,16 +466,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return null; return null;
} }
Entity entity; Entity entity;
switch (this.getType()) { switch (this.getType().toString()) {
case DROPPED_ITEM: case "DROPPED_ITEM":
return world.dropItem(location, this.stack); return world.dropItem(location, this.stack);
case PLAYER: case "PLAYER":
case LEASH_HITCH: case "LEASH_HITCH":
return null; return null;
case ITEM_FRAME: case "ITEM_FRAME":
entity = world.spawn(location, ItemFrame.class); entity = world.spawn(location, ItemFrame.class);
break; break;
case PAINTING: case "PAINTING":
entity = world.spawn(location, Painting.class); entity = world.spawn(location, Painting.class);
break; break;
default: default:
@ -504,73 +507,73 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (this.noGravity) { if (this.noGravity) {
entity.setGravity(false); entity.setGravity(false);
} }
switch (entity.getType()) { switch (entity.getType().toString()) {
case BOAT: case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
boat.setWoodType(TreeSpecies.values()[dataByte]); boat.setWoodType(TreeSpecies.values()[dataByte]);
return entity; return entity;
case SLIME: case "SLIME":
((Slime) entity).setSize(this.dataByte); ((Slime) entity).setSize(this.dataByte);
return entity; return entity;
case ARROW: case "ARROW":
case EGG: case "EGG":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case ENDER_PEARL: case "ENDER_PEARL":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case DROPPED_ITEM: case "DROPPED_ITEM":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case FALLING_BLOCK: case "FALLING_BLOCK":
case FIREBALL: case "FIREBALL":
case FIREWORK: case "FIREWORK":
case FISHING_HOOK: case "FISHING_HOOK":
case LEASH_HITCH: case "LEASH_HITCH":
case LIGHTNING: case "LIGHTNING":
case MINECART: case "MINECART":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case MINECART_TNT: case "MINECART_TNT":
case PLAYER: case "PLAYER":
case PRIMED_TNT: case "PRIMED_TNT":
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case SNOWBALL: case "SNOWBALL":
case SPLASH_POTION: case "SPLASH_POTION":
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case SHULKER_BULLET: case "SHULKER_BULLET":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case WITHER_SKULL: case "WITHER_SKULL":
case MINECART_FURNACE: case "MINECART_FURNACE":
case LLAMA_SPIT: case "LLAMA_SPIT":
case TRIDENT: case "TRIDENT":
case UNKNOWN: case "UNKNOWN":
// Do this stuff later // Do this stuff later
return entity; return entity;
// MISC // // MISC //
case ITEM_FRAME: case "ITEM_FRAME":
ItemFrame itemframe = (ItemFrame) entity; ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]); itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack); itemframe.setItem(this.stack);
return entity; return entity;
case PAINTING: case "PAINTING":
Painting painting = (Painting) entity; Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true); painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true); painting.setArt(Art.getByName(this.dataString), true);
return entity; return entity;
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_HOPPER: case "MINECART_HOPPER":
restoreInventory((InventoryHolder) entity); restoreInventory((InventoryHolder) entity);
return entity; return entity;
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case HORSE: case "HORSE":
case LLAMA: case "LLAMA":
case SKELETON_HORSE: case "SKELETON_HORSE":
case DONKEY: case "DONKEY":
case MULE: case "MULE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
horse.setJumpStrength(this.horse.jump); horse.setJumpStrength(this.horse.jump);
if (horse instanceof ChestedHorse) { if (horse instanceof ChestedHorse) {
@ -586,14 +589,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreInventory(horse); restoreInventory(horse);
return entity; return entity;
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case WOLF: case "WOLF":
case OCELOT: case "OCELOT":
restoreTameable((Tameable) entity); restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
// END AGEABLE // // END AGEABLE //
case SHEEP: case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) { if (this.dataByte == 1) {
sheep.setSheared(true); sheep.setSheared(true);
@ -604,25 +607,25 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreAgeable(sheep); restoreAgeable(sheep);
restoreLiving(sheep); restoreLiving(sheep);
return sheep; return sheep;
case VILLAGER: case "VILLAGER":
case CHICKEN: case "CHICKEN":
case COW: case "COW":
case TURTLE: case "TURTLE":
case POLAR_BEAR: case "POLAR_BEAR":
case MUSHROOM_COW: case "MUSHROOM_COW":
case PIG: case "PIG":
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
// END AGEABLE // // END AGEABLE //
case RABBIT: case "RABBIT":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
} }
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ARMOR_STAND: case "ARMOR_STAND":
// CHECK positions // CHECK positions
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) { if (this.inventory[0] != null) {
@ -688,42 +691,45 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
restoreLiving(stand); restoreLiving(stand);
return stand; return stand;
case BAT: case "BAT":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Bat) entity).setAwake(true); ((Bat) entity).setAwake(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ENDER_DRAGON: case "ENDER_DRAGON":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]); ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ENDERMITE: case "ENDERMITE":
case GHAST: case "GHAST":
case MAGMA_CUBE: case "MAGMA_CUBE":
case SQUID: case "SQUID":
case PIG_ZOMBIE: case "PIG_ZOMBIE":
case ZOMBIE: case "HOGLIN":
case WITHER: case "PIGLIN":
case WITCH: case "ZOMBIFIED_PIGLIN":
case SPIDER: case "ZOMBIE":
case CAVE_SPIDER: case "WITHER":
case SILVERFISH: case "WITCH":
case GIANT: case "SPIDER":
case ENDERMAN: case "CAVE_SPIDER":
case CREEPER: case "SILVERFISH":
case BLAZE: case "GIANT":
case SNOWMAN: case "ENDERMAN":
case SHULKER: case "CREEPER":
case GUARDIAN: case "BLAZE":
case ELDER_GUARDIAN: case "SNOWMAN":
case SKELETON: case "SHULKER":
case WITHER_SKELETON: case "GUARDIAN":
case "ELDER_GUARDIAN":
case "SKELETON":
case "WITHER_SKELETON":
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case IRON_GOLEM: case "IRON_GOLEM":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((IronGolem) entity).setPlayerCreated(true); ((IronGolem) entity).setPlayerCreated(true);
} }

View File

@ -100,15 +100,15 @@ public class EntitySpawnListener implements Listener {
if (!originWorld.equals(world)) { if (!originWorld.equals(world)) {
if (!ignoreTP) { if (!ignoreTP) {
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) { if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
if (entity.getType() == EntityType.PLAYER) {
return;
}
try { try {
ignoreTP = true; ignoreTP = true;
PaperLib.teleportAsync(entity, origin); PaperLib.teleportAsync(entity, origin);
} finally { } finally {
ignoreTP = false; ignoreTP = false;
} }
if (entity.getType() == EntityType.PLAYER) {
return;
}
if (entity.getLocation().getWorld().equals(world)) { if (entity.getLocation().getWorld().equals(world)) {
entity.remove(); entity.remove();
} }

View File

@ -31,8 +31,11 @@ import com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent;
import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent; import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent;
import com.destroystokyo.paper.event.entity.SlimePathfindEvent; import com.destroystokyo.paper.event.entity.SlimePathfindEvent;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent; import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.Command;
import com.plotsquared.core.command.MainCommand;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
@ -56,6 +59,12 @@ import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
/** /**
* Events specific to Paper. Some toit nups here * Events specific to Paper. Some toit nups here
*/ */
@ -270,7 +279,7 @@ public class PaperListener implements Listener {
} }
final int tileEntityCount = event.getBlock().getChunk().getTileEntities(false).length; final int tileEntityCount = event.getBlock().getChunk().getTileEntities(false).length;
if (tileEntityCount >= Settings.Chunk_Processor.MAX_TILES) { if (tileEntityCount >= Settings.Chunk_Processor.MAX_TILES) {
final PlotPlayer plotPlayer = BukkitUtil.getPlayer(event.getPlayer()); final PlotPlayer<?> plotPlayer = BukkitUtil.getPlayer(event.getPlayer());
Captions.TILE_ENTITY_CAP_REACHED.send(plotPlayer, Settings.Chunk_Processor.MAX_TILES); Captions.TILE_ENTITY_CAP_REACHED.send(plotPlayer, Settings.Chunk_Processor.MAX_TILES);
event.setCancelled(true); event.setCancelled(true);
event.setBuild(false); event.setBuild(false);
@ -299,11 +308,50 @@ public class PaperListener implements Listener {
if (!PlotSquared.get().hasPlotArea(location.getWorld())) { if (!PlotSquared.get().hasPlotArea(location.getWorld())) {
return; return;
} }
PlotPlayer pp = BukkitUtil.getPlayer((Player) shooter); PlotPlayer<?> pp = BukkitUtil.getPlayer((Player) shooter);
Plot plot = location.getOwnedPlot(); Plot plot = location.getOwnedPlot();
if (plot != null && !plot.isAdded(pp.getUUID())) { if (plot != null && !plot.isAdded(pp.getUUID())) {
entity.remove(); entity.remove();
event.setCancelled(true); event.setCancelled(true);
} }
} }
@EventHandler public void onAsyncTabCompletion(final AsyncTabCompleteEvent event) {
if (!Settings.Paper_Components.ASYNC_TAB_COMPLETION) {
return;
}
String buffer = event.getBuffer();
if (!(event.getSender() instanceof Player)) {
return;
}
if ((!event.isCommand() && !buffer.startsWith("/")) || buffer.indexOf(' ') == -1) {
return;
}
if (buffer.startsWith("/")) {
buffer = buffer.substring(1);
}
final String[] unprocessedArgs = buffer.split(Pattern.quote(" "));
if (unprocessedArgs.length == 1) {
return; // We don't do anything in this case
} else if (!Settings.Enabled_Components.TAB_COMPLETED_ALIASES
.contains(unprocessedArgs[0].toLowerCase(Locale.ENGLISH))) {
return;
}
final String[] args = new String[unprocessedArgs.length - 1];
System.arraycopy(unprocessedArgs, 1, args, 0, args.length);
try {
final PlotPlayer<?> player = BukkitUtil.getPlayer((Player) event.getSender());
final Collection<Command> objects = MainCommand.getInstance().tab(player, args, buffer.endsWith(" "));
if (objects == null) {
return;
}
final List<String> result = new ArrayList<>();
for (final com.plotsquared.core.command.Command o : objects) {
result.add(o.toString());
}
event.setCompletions(result);
event.setHandled(true);
} catch (final Exception ignored) {}
}
} }

View File

@ -36,6 +36,9 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/** /**
* Default Bukkit world manager. It will handle world creation by * Default Bukkit world manager. It will handle world creation by
@ -76,4 +79,13 @@ public class BukkitWorldManager implements PlatformWorldManager<World> {
return "bukkit"; return "bukkit";
} }
@Override public Collection<String> getWorlds() {
final List<World> worlds = Bukkit.getWorlds();
final List<String> worldNames = new ArrayList<>();
for (final World world : worlds) {
worldNames.add(world.getName());
}
return worldNames;
}
} }

View File

@ -25,9 +25,12 @@
*/ */
package com.plotsquared.bukkit.placeholder; package com.plotsquared.bukkit.placeholder;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.uuid.UUIDHandler; import com.plotsquared.core.plot.flag.GlobalFlagContainer;
import com.plotsquared.core.plot.flag.PlotFlag;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -58,31 +61,31 @@ public class Placeholders extends PlaceholderExpansion {
} }
@Override public String getVersion() { @Override public String getVersion() {
return "2.4"; return "2.5";
} }
@Override public String onPlaceholderRequest(Player p, String identifier) { @Override public String onPlaceholderRequest(Player p, String identifier) {
final PlotPlayer pl = PlotPlayer.get(p.getName()); final PlotPlayer pl = PlotSquared.imp().getPlayerManager().getPlayerIfExists(p.getUniqueId());
if (pl == null) { if (pl == null) {
return ""; return "";
} }
if (identifier.startsWith("has_plot_")) { if (identifier.startsWith("has_plot_")) {
if (identifier.split("has_plot_").length != 2) identifier = identifier.substring("has_plot_".length());
if (identifier.isEmpty())
return ""; return "";
identifier = identifier.split("has_plot_")[1];
return pl.getPlotCount(identifier) > 0 ? return pl.getPlotCount(identifier) > 0 ?
PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanTrue() :
PlaceholderAPIPlugin.booleanFalse(); PlaceholderAPIPlugin.booleanFalse();
} }
if (identifier.startsWith("plot_count_")) { if (identifier.startsWith("plot_count_")) {
if (identifier.split("plot_count_").length != 2) identifier = identifier.substring("plot_count_".length());
if (identifier.isEmpty())
return ""; return "";
identifier = identifier.split("plot_count_")[1];
return String.valueOf(pl.getPlotCount(identifier)); return String.valueOf(pl.getPlotCount(identifier));
} }
@ -122,7 +125,9 @@ public class Placeholders extends PlaceholderExpansion {
if (uid == null) { if (uid == null) {
return ""; return "";
} }
String name = UUIDHandler.getName(uid);
String name = PlotSquared.get().getImpromptuUUIDPipeline()
.getSingle(uid, Settings.UUID.BLOCKING_TIMEOUT);
if (name != null) { if (name != null) {
return name; return name;
@ -178,6 +183,39 @@ public class Placeholders extends PlaceholderExpansion {
default: default:
break; break;
} }
if (identifier.startsWith("currentplot_localflag_")) {
return getFlagValue(plot, identifier.substring("currentplot_localflag_".length()),
false);
}
if (identifier.startsWith("currentplot_flag_")) {
return getFlagValue(plot, identifier.substring("currentplot_flag_".length()), true);
}
return ""; return "";
} }
/**
* Return the flag value from its name on the current plot.
* If the flag doesn't exist it returns an empty string.
* If the flag exists but it is not set on current plot and the parameter inherit is set to true,
* it returns the default value.
*
* @param plot Current plot where the player is
* @param flagName Name of flag to get from current plot
* @param inherit Define if it returns only the flag set on currentplot or also inherited flag
* @return The value of flag serialized in string
*/
private String getFlagValue(final Plot plot, final String flagName, final boolean inherit) {
if (flagName.isEmpty())
return "";
final PlotFlag<?, ?> flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName);
if (flag == null)
return "";
if (inherit) {
return plot.getFlag(flag).toString();
} else {
final PlotFlag<?, ?> plotFlag = plot.getFlagContainer().queryLocal(flag.getClass());
return (plotFlag != null) ? plotFlag.getValue().toString() : "";
}
}
} }

View File

@ -25,9 +25,11 @@
*/ */
package com.plotsquared.bukkit.player; package com.plotsquared.bukkit.player;
import com.google.common.base.Charsets;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
@ -35,7 +37,6 @@ import com.plotsquared.core.plot.PlotWeather;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
@ -62,12 +63,11 @@ import static com.sk89q.worldedit.world.gamemode.GameModes.CREATIVE;
import static com.sk89q.worldedit.world.gamemode.GameModes.SPECTATOR; import static com.sk89q.worldedit.world.gamemode.GameModes.SPECTATOR;
import static com.sk89q.worldedit.world.gamemode.GameModes.SURVIVAL; import static com.sk89q.worldedit.world.gamemode.GameModes.SURVIVAL;
public class BukkitPlayer extends PlotPlayer { public class BukkitPlayer extends PlotPlayer<Player> {
private static boolean CHECK_EFFECTIVE = true; private static boolean CHECK_EFFECTIVE = true;
public final Player player; public final Player player;
private boolean offline; private boolean offline;
private UUID uuid;
private String name; private String name;
/** /**
@ -77,30 +77,45 @@ public class BukkitPlayer extends PlotPlayer {
* @param player Bukkit player instance * @param player Bukkit player instance
*/ */
public BukkitPlayer(@NotNull final Player player) { public BukkitPlayer(@NotNull final Player player) {
this.player = player; this(player, false);
super.populatePersistentMetaMap();
} }
public BukkitPlayer(@NotNull final Player player, final boolean offline) { public BukkitPlayer(@NotNull final Player player, final boolean offline) {
this(player, offline, true);
}
public BukkitPlayer(@NotNull final Player player, final boolean offline, final boolean realPlayer) {
this.player = player; this.player = player;
this.offline = offline; this.offline = offline;
super.populatePersistentMetaMap(); if (realPlayer) {
super.populatePersistentMetaMap();
}
} }
@Override public Actor toActor() { @Override public Actor toActor() {
return BukkitAdapter.adapt(player); return BukkitAdapter.adapt(player);
} }
@Override public Player getPlatformPlayer() {
return this.player;
}
@NotNull @Override public Location getLocation() { @NotNull @Override public Location getLocation() {
final Location location = super.getLocation(); final Location location = super.getLocation();
return location == null ? BukkitUtil.getLocation(this.player) : location; return location == null ? BukkitUtil.getLocation(this.player) : location;
} }
@NotNull @Override public UUID getUUID() { @NotNull @Override public UUID getUUID() {
if (this.uuid == null) { if (Settings.UUID.OFFLINE) {
this.uuid = UUIDHandler.getUUID(this); if (Settings.UUID.FORCE_LOWERCASE) {
return UUID.nameUUIDFromBytes(("OfflinePlayer:" +
getName().toLowerCase()).getBytes(Charsets.UTF_8));
} else {
return UUID.nameUUIDFromBytes(("OfflinePlayer:" +
getName()).getBytes(Charsets.UTF_8));
}
} }
return this.uuid; return player.getUniqueId();
} }
@Override public long getLastPlayed() { @Override public long getLastPlayed() {
@ -140,8 +155,8 @@ public class BukkitPlayer extends PlotPlayer {
} }
@Override public boolean hasPermission(final String permission) { @Override public boolean hasPermission(final String permission) {
if (this.offline && EconHandler.manager != null) { if (this.offline && EconHandler.getEconHandler() != null) {
return EconHandler.manager.hasPermission(getName(), permission); return EconHandler.getEconHandler().hasPermission(getName(), permission);
} }
return this.player.hasPermission(permission); return this.player.hasPermission(permission);
} }

View File

@ -23,44 +23,46 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.plotsquared.bukkit.util.uuid; package com.plotsquared.bukkit.player;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer; import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
public class DefaultUUIDWrapper extends UUIDWrapper { /**
* Player manager providing {@link BukkitPlayer Bukkit players}
*/
public class BukkitPlayerManager extends PlayerManager<BukkitPlayer, Player> {
@NotNull @Override public UUID getUUID(PlotPlayer player) { @NotNull @Override public BukkitPlayer getPlayer(@NotNull final Player object) {
return ((BukkitPlayer) player).player.getUniqueId(); try {
return getPlayer(object.getUniqueId());
} catch (final NoSuchPlayerException exception) {
return new BukkitPlayer(object, object.isOnline(), false);
}
} }
@Override public UUID getUUID(OfflinePlotPlayer player) { @Override @NotNull public BukkitPlayer createPlayer(@NotNull final UUID uuid) {
return player.getUUID(); final Player player = Bukkit.getPlayer(uuid);
if (player == null || !player.isOnline()) {
throw new NoSuchPlayerException(uuid);
}
return new BukkitPlayer(player);
} }
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) { @Nullable @Override public BukkitOfflinePlayer getOfflinePlayer(@Nullable final UUID uuid) {
if (uuid == null) {
return null;
}
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid)); return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid));
} }
@Override public UUID getUUID(String name) { @NotNull @Override public BukkitOfflinePlayer getOfflinePlayer(@NotNull final String username) {
return Bukkit.getOfflinePlayer(name).getUniqueId(); return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(username));
} }
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
return Arrays.stream(ops).map(BukkitOfflinePlayer::new).toArray(BukkitOfflinePlayer[]::new);
}
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
}
} }

View File

@ -31,6 +31,7 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.queue.BasicLocalBlockQueue; import com.plotsquared.core.queue.BasicLocalBlockQueue;
import com.plotsquared.core.util.BlockUtil; import com.plotsquared.core.util.BlockUtil;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
@ -50,7 +51,6 @@ import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Container; import org.bukkit.block.Container;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.BlockInventoryHolder;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -117,9 +117,6 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
@Override public final void setComponents(LocalChunk lc) @Override public final void setComponents(LocalChunk lc)
throws ExecutionException, InterruptedException { throws ExecutionException, InterruptedException {
setBaseBlocks(lc); setBaseBlocks(lc);
if (setBiome() && lc.biomes != null) {
setBiomes(lc);
}
} }
public void setBaseBlocks(LocalChunk localChunk) { public void setBaseBlocks(LocalChunk localChunk) {
@ -165,6 +162,22 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
} }
} }
} }
if (setBiome() && localChunk.biomes != null) {
for (int x = 0; x < localChunk.biomes.length; x++) {
BiomeType[] biomeZ = localChunk.biomes[x];
if (biomeZ != null) {
for (int z = 0; z < biomeZ.length; z++) {
if (biomeZ[z] != null) {
BiomeType biomeType = biomeZ[z];
Biome biome = BukkitAdapter.adapt(biomeType);
worldObj.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z,
biome);
}
}
}
}
}
}; };
if (isForceSync()) { if (isForceSync()) {
chunkConsumer.accept(getChunk(worldObj, localChunk)); chunkConsumer.accept(getChunk(worldObj, localChunk));

View File

@ -27,49 +27,39 @@ package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer; import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.OfflinePlotPlayer; import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
public class BukkitEconHandler extends EconHandler { public class BukkitEconHandler extends EconHandler {
private Economy econ; private Economy econ;
private Permission perms;
@Override
public boolean init() { public boolean init() {
if (this.econ == null || this.perms == null) { if (this.econ == null) {
setupPermissions();
setupEconomy(); setupEconomy();
} }
return this.econ != null && this.perms != null; return this.econ != null;
} }
private boolean setupPermissions() { private void setupEconomy() {
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
return this.perms != null;
}
private boolean setupEconomy() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) { if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
return false; return;
} }
RegisteredServiceProvider<Economy> economyProvider = RegisteredServiceProvider<Economy> economyProvider =
Bukkit.getServer().getServicesManager().getRegistration(Economy.class); Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
if (economyProvider != null) { if (economyProvider != null) {
this.econ = economyProvider.getProvider(); this.econ = economyProvider.getProvider();
} }
return this.econ != null;
} }
@Override public double getMoney(PlotPlayer player) { @Override public double getMoney(PlotPlayer<?> player) {
double bal = super.getMoney(player); double bal = super.getMoney(player);
if (Double.isNaN(bal)) { if (Double.isNaN(bal)) {
return this.econ.getBalance(((BukkitPlayer) player).player); return this.econ.getBalance(((BukkitPlayer) player).player);
@ -77,11 +67,11 @@ public class BukkitEconHandler extends EconHandler {
return bal; return bal;
} }
@Override public void withdrawMoney(PlotPlayer player, double amount) { @Override public void withdrawMoney(PlotPlayer<?> player, double amount) {
this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount); this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount);
} }
@Override public void depositMoney(PlotPlayer player, double amount) { @Override public void depositMoney(PlotPlayer<?> player, double amount) {
this.econ.depositPlayer(((BukkitPlayer) player).player, amount); this.econ.depositPlayer(((BukkitPlayer) player).player, amount);
} }
@ -89,20 +79,19 @@ public class BukkitEconHandler extends EconHandler {
this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount); this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
} }
@Override public boolean hasPermission(String world, String player, String perm) { /**
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm); * @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
} */
@Deprecated @Override public boolean hasPermission(String world, String player, String perm) {
@Override public double getBalance(PlotPlayer player) { if (PlotSquared.imp().getPermissionHandler() != null) {
return this.econ.getBalance(player.getName()); return PlotSquared.imp().getPermissionHandler().hasPermission(world, player, perm);
}
public void setPermission(String world, String player, String perm, boolean value) {
if (value) {
this.perms.playerAdd(world, player, perm);
} else { } else {
this.perms.playerRemove(world, player, perm); return false;
} }
} }
@Override public double getBalance(PlotPlayer<?> player) {
return this.econ.getBalance(player.getName());
}
} }

View File

@ -0,0 +1,59 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
public class BukkitPermHandler extends PermHandler {
private Permission perms;
@Override
public boolean init() {
if (this.perms == null) {
setupPermissions();
}
return this.perms != null;
}
private void setupPermissions() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
return;
}
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
}
@Override public boolean hasPermission(String world, String player, String perm) {
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
}
}

View File

@ -348,7 +348,7 @@ public class BukkitRegionManager extends RegionManager {
CuboidRegion currentPlotClear = RegionUtil CuboidRegion currentPlotClear = RegionUtil
.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()); .createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
map.saveEntitiesOut(chunkObj, currentPlotClear); map.saveEntitiesOut(chunkObj, currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager.manager AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
.setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() { .setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
@Override public void run(ScopedLocalBlockQueue value) { @Override public void run(ScopedLocalBlockQueue value) {
Location min = value.getMin(); Location min = value.getMin();

View File

@ -33,6 +33,7 @@ import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.SetupObject; import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.setup.PlotAreaBuilder;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -97,7 +98,7 @@ public class BukkitSetupUtils extends SetupUtils {
Bukkit.unloadWorld(world, false); Bukkit.unloadWorld(world, false);
} }
@Override public String setupWorld(SetupObject object) { @Deprecated @Override public String setupWorld(SetupObject object) {
SetupUtils.manager.updateGenerators(); SetupUtils.manager.updateGenerators();
ConfigurationNode[] steps = object.step == null ? new ConfigurationNode[0] : object.step; ConfigurationNode[] steps = object.step == null ? new ConfigurationNode[0] : object.step;
String world = object.world; String world = object.world;
@ -209,6 +210,119 @@ public class BukkitSetupUtils extends SetupUtils {
return object.world; return object.world;
} }
@Override public String setupWorld(PlotAreaBuilder builder) {
SetupUtils.manager.updateGenerators();
ConfigurationNode[] steps = builder.settingsNodesWrapper() == null ?
new ConfigurationNode[0] : builder.settingsNodesWrapper().getSettingsNodes();
String world = builder.worldName();
PlotAreaType type = builder.plotAreaType();
String worldPath = "worlds." + builder.worldName();
switch (type) {
case PARTIAL: {
if (builder.areaName() != null) {
if (!PlotSquared.get().worlds.contains(worldPath)) {
PlotSquared.get().worlds.createSection(worldPath);
}
ConfigurationSection worldSection =
PlotSquared.get().worlds.getConfigurationSection(worldPath);
String areaName = builder.areaName() + "-" + builder.minimumId() + "-" + builder.maximumId();
String areaPath = "areas." + areaName;
if (!worldSection.contains(areaPath)) {
worldSection.createSection(areaPath);
}
ConfigurationSection areaSection =
worldSection.getConfigurationSection(areaPath);
HashMap<String, Object> options = new HashMap<>();
for (ConfigurationNode step : steps) {
options.put(step.getConstant(), step.getValue());
}
options.put("generator.type", builder.plotAreaType().toString());
options.put("generator.terrain", builder.terrainType().toString());
options.put("generator.plugin", builder.plotManager());
if (builder.generatorName() != null && !builder.generatorName()
.equals(builder.plotManager())) {
options.put("generator.init", builder.generatorName());
}
for (Entry<String, Object> entry : options.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (worldSection.contains(key)) {
Object current = worldSection.get(key);
if (!Objects.equals(value, current)) {
areaSection.set(key, value);
}
} else {
worldSection.set(key, value);
}
}
}
GeneratorWrapper<?> gen = SetupUtils.generators.get(builder.generatorName());
if (gen != null && gen.isFull()) {
builder.generatorName(null);
}
break;
}
case AUGMENTED: {
if (!builder.plotManager().endsWith(":single")) {
if (!PlotSquared.get().worlds.contains(worldPath)) {
PlotSquared.get().worlds.createSection(worldPath);
}
if (steps.length != 0) {
ConfigurationSection worldSection =
PlotSquared.get().worlds.getConfigurationSection(worldPath);
for (ConfigurationNode step : steps) {
worldSection.set(step.getConstant(), step.getValue());
}
}
PlotSquared.get().worlds
.set("worlds." + world + ".generator.type", builder.plotAreaType().toString());
PlotSquared.get().worlds
.set("worlds." + world + ".generator.terrain", builder.terrainType().toString());
PlotSquared.get().worlds
.set("worlds." + world + ".generator.plugin", builder.plotManager());
if (builder.generatorName() != null && !builder.generatorName()
.equals(builder.plotManager())) {
PlotSquared.get().worlds
.set("worlds." + world + ".generator.init", builder.generatorName());
}
}
GeneratorWrapper<?> gen = SetupUtils.generators.get(builder.generatorName());
if (gen != null && gen.isFull()) {
builder.generatorName(null);
}
break;
}
case NORMAL: {
if (steps.length != 0) {
if (!PlotSquared.get().worlds.contains(worldPath)) {
PlotSquared.get().worlds.createSection(worldPath);
}
ConfigurationSection worldSection =
PlotSquared.get().worlds.getConfigurationSection(worldPath);
for (ConfigurationNode step : steps) {
worldSection.set(step.getConstant(), step.getValue());
}
}
break;
}
}
try {
PlotSquared.get().worlds.save(PlotSquared.get().worldsFile);
} catch (IOException e) {
e.printStackTrace();
}
Objects.requireNonNull(PlotSquared.imp()).getWorldManager()
.handleWorldCreation(builder.worldName(), builder.generatorName());
if (Bukkit.getWorld(world) != null) {
return world;
}
return builder.worldName();
}
@Override public String getGenerator(PlotArea plotArea) { @Override public String getGenerator(PlotArea plotArea) {
if (SetupUtils.generators.isEmpty()) { if (SetupUtils.generators.isEmpty()) {
updateGenerators(); updateGenerators();

View File

@ -27,6 +27,7 @@ package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.BukkitMain; import com.plotsquared.bukkit.BukkitMain;
import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
@ -35,11 +36,11 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.BlockUtil; import com.plotsquared.core.util.BlockUtil;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
@ -113,14 +114,16 @@ public class BukkitUtil extends WorldUtil {
private static World lastWorld = null; private static World lastWorld = null;
private static Player lastPlayer = null; private static Player lastPlayer = null;
private static PlotPlayer lastPlotPlayer = null; private static BukkitPlayer lastPlotPlayer = null;
public static void removePlayer(String player) { public static void removePlayer(UUID uuid) {
lastPlayer = null; lastPlayer = null;
lastPlotPlayer = null; lastPlotPlayer = null;
// Make sure that it's removed internally
PlotSquared.imp().getPlayerManager().removePlayer(uuid);
} }
public static PlotPlayer getPlayer(@NonNull final OfflinePlayer op) { public static PlotPlayer<Player> getPlayer(@NonNull final OfflinePlayer op) {
if (op.isOnline()) { if (op.isOnline()) {
return getPlayer(op.getPlayer()); return getPlayer(op.getPlayer());
} }
@ -165,7 +168,7 @@ public class BukkitUtil extends WorldUtil {
* @return a {@code PlotPlayer} * @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object) * @see PlotPlayer#wrap(Object)
*/ */
public static PlotPlayer wrapPlayer(OfflinePlayer player) { public static PlotPlayer<?> wrapPlayer(OfflinePlayer player) {
return PlotPlayer.wrap(player); return PlotPlayer.wrap(player);
} }
@ -177,7 +180,7 @@ public class BukkitUtil extends WorldUtil {
* @return a {@code PlotPlayer} * @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object) * @see PlotPlayer#wrap(Object)
*/ */
public static PlotPlayer wrapPlayer(Player player) { public static PlotPlayer<?> wrapPlayer(Player player) {
return PlotPlayer.wrap(player); return PlotPlayer.wrap(player);
} }
@ -189,7 +192,7 @@ public class BukkitUtil extends WorldUtil {
* @return a {@code PlotPlayer} * @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object) * @see PlotPlayer#wrap(Object)
*/ */
@Override public PlotPlayer wrapPlayer(UUID uuid) { @Override public PlotPlayer<?> wrapPlayer(UUID uuid) {
return PlotPlayer.wrap(Bukkit.getOfflinePlayer(uuid)); return PlotPlayer.wrap(Bukkit.getOfflinePlayer(uuid));
} }
@ -200,7 +203,7 @@ public class BukkitUtil extends WorldUtil {
* @return the number of allowed plots * @return the number of allowed plots
*/ */
public static int getAllowedPlots(Player player) { public static int getAllowedPlots(Player player) {
PlotPlayer plotPlayer = PlotPlayer.wrap(player); PlotPlayer<?> plotPlayer = PlotPlayer.wrap(player);
return plotPlayer.getAllowedPlots(); return plotPlayer.getAllowedPlots();
} }
@ -226,7 +229,7 @@ public class BukkitUtil extends WorldUtil {
if (world == null) { if (world == null) {
return new HashSet<>(); return new HashSet<>();
} }
return PlotPlayer.wrap(player).getPlots(world); return BukkitPlayer.wrap(player).getPlots(world);
} }
/** /**
@ -264,19 +267,12 @@ public class BukkitUtil extends WorldUtil {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), caption); MainUtil.sendMessage(BukkitUtil.getPlayer(player), caption);
} }
public static PlotPlayer getPlayer(@NonNull final Player player) { public static BukkitPlayer getPlayer(@NonNull final Player player) {
if (player == lastPlayer) { if (player == lastPlayer) {
return lastPlotPlayer; return lastPlotPlayer;
} }
final String name = player.getName(); final PlayerManager<?, ?> playerManager = PlotSquared.imp().getPlayerManager();
final PlotPlayer plotPlayer = UUIDHandler.getPlayer(name); return ((BukkitPlayerManager) playerManager).getPlayer(player);
if (plotPlayer != null) {
return plotPlayer;
}
lastPlotPlayer = new BukkitPlayer(player);
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
lastPlayer = player;
return lastPlotPlayer;
} }
public static Location getLocation(@NonNull final org.bukkit.Location location) { public static Location getLocation(@NonNull final org.bukkit.Location location) {

View File

@ -1,167 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.ReflectionUtils.RefClass;
import com.plotsquared.core.util.ReflectionUtils.RefConstructor;
import com.plotsquared.core.util.ReflectionUtils.RefField;
import com.plotsquared.core.util.ReflectionUtils.RefMethod;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.math.BlockVector2;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
/**
* An utility that can be used to send chunks, rather than using bukkit code
* to do so (uses heavy NMS).
*/
public class SendChunk {
private final RefMethod methodGetHandlePlayer;
private final RefMethod methodGetHandleChunk;
private final RefConstructor mapChunk;
private final RefField connection;
private final RefMethod send;
private final RefMethod methodInitLighting;
/**
* Constructor.
*/
public SendChunk() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
this.methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle");
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
RefClass classChunk = getRefClass("{nms}.Chunk");
this.methodInitLighting = classChunk.getMethod("initLighting");
RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
this.mapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), int.class);
RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
this.connection = classEntityPlayer.getField("playerConnection");
RefClass classPacket = getRefClass("{nms}.Packet");
RefClass classConnection = getRefClass("{nms}.PlayerConnection");
this.send = classConnection.getMethod("sendPacket", classPacket.getRealClass());
}
public void sendChunk(Collection<Chunk> input) {
HashSet<Chunk> chunks = new HashSet<>(input);
HashMap<String, ArrayList<Chunk>> map = new HashMap<>();
int view = Bukkit.getServer().getViewDistance();
for (Chunk chunk : chunks) {
String world = chunk.getWorld().getName();
ArrayList<Chunk> list = map.computeIfAbsent(world, k -> new ArrayList<>());
list.add(chunk);
Object c = this.methodGetHandleChunk.of(chunk).call();
this.methodInitLighting.of(c).call();
}
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
Plot plot = pp.getCurrentPlot();
Location location = null;
String world;
if (plot != null) {
world = plot.getWorldName();
} else {
location = pp.getLocation();
world = location.getWorld();
}
ArrayList<Chunk> list = map.get(world);
if (list == null) {
continue;
}
if (location == null) {
location = pp.getLocation();
}
int chunkX = location.getX() >> 4;
int chunkZ = location.getZ() >> 4;
Player player = ((BukkitPlayer) pp).player;
Object entity = this.methodGetHandlePlayer.of(player).call();
for (Chunk chunk : list) {
int dx = Math.abs(chunkX - chunk.getX());
int dz = Math.abs(chunkZ - chunk.getZ());
if ((dx > view) || (dz > view)) {
continue;
}
Object c = this.methodGetHandleChunk.of(chunk).call();
chunks.remove(chunk);
Object con = this.connection.of(entity).get();
Object packet = null;
try {
packet = this.mapChunk.create(c, 65535);
} catch (Exception ignored) {
}
if (packet == null) {
PlotSquared.debug("Error with PacketPlayOutMapChunk reflection.");
}
this.send.of(con).call(packet);
}
}
for (final Chunk chunk : chunks) {
TaskManager.runTask(() -> {
try {
chunk.unload(true);
} catch (Throwable ignored) {
String worldName = chunk.getWorld().getName();
PlotSquared.debug(
"$4Could not save chunk: " + worldName + ';' + chunk.getX() + ";" + chunk
.getZ());
PlotSquared.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
PlotSquared.debug("$3 - $4" + worldName + "/level.dat or " + worldName
+ "/level_old.dat may be corrupt (try repairing or removing these)");
}
});
}
}
public void sendChunk(String worldName, Collection<BlockVector2> chunkLocations) {
World myWorld = Bukkit.getWorld(worldName);
ArrayList<Chunk> chunks = new ArrayList<>();
for (BlockVector2 loc : chunkLocations) {
if (myWorld.isChunkLoaded(loc.getX(), loc.getZ())) {
PaperLib.getChunkAtAsync(myWorld, loc.getX(), loc.getZ()).thenAccept(chunks::add);
}
}
sendChunk(chunks);
}
}

View File

@ -1,289 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util.uuid;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.plot.expiration.ExpireManager;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.plotsquared.core.util.uuid.UUIDHandlerImplementation;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.Tag;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.GZIPInputStream;
public class FileUUIDHandler extends UUIDHandlerImplementation {
public FileUUIDHandler(UUIDWrapper wrapper) {
super(wrapper);
}
@Override public boolean startCaching(Runnable whenDone) {
return super.startCaching(whenDone) && cache(whenDone);
}
private Tag readTag(File file) throws IOException {
// Don't chain the creation of the GZIP stream and the NBT stream, because their
// constructors may throw an IOException.
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
NBTInputStream nbtInputStream = new NBTInputStream(gzipInputStream)) {
return nbtInputStream.readNamedTag().getTag();
}
}
public boolean cache(final Runnable whenDone) {
final File container = Bukkit.getWorldContainer();
List<World> worlds = Bukkit.getWorlds();
final String world;
if (worlds.isEmpty()) {
world = "world";
} else {
world = worlds.get(0).getName();
}
TaskManager.runTaskAsync(() -> {
PlotSquared.debug(Captions.PREFIX + "Starting player data caching for: " + world);
File uuidFile = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt");
if (uuidFile.exists()) {
try {
List<String> lines =
Files.readAllLines(uuidFile.toPath(), StandardCharsets.UTF_8);
for (String line : lines) {
try {
line = line.trim();
if (line.isEmpty()) {
continue;
}
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
String[] split = line.split("\\|");
String name = split[0];
if (name.isEmpty() || (name.length() > 16) || !StringMan
.isAlphanumericUnd(name)) {
continue;
}
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
if (uuid == null) {
continue;
}
UUIDHandler.add(new StringWrapper(name), uuid);
} catch (Exception e2) {
e2.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<>());
if (Settings.UUID.NATIVE_UUID_PROVIDER) {
HashSet<UUID> all = UUIDHandler.getAllUUIDS();
PlotSquared.debug("Fast mode UUID caching enabled!");
File playerDataFolder = new File(container, world + File.separator + "playerdata");
String[] dat = playerDataFolder.list(new DatFileFilter());
boolean check = all.isEmpty();
if (dat != null) {
for (String current : dat) {
String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
if (check || all.remove(uuid)) {
File file = new File(playerDataFolder, current);
CompoundTag compound = (CompoundTag) readTag(file);
if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\"");
} else {
Map<String, Tag> compoundMap = compound.getValue();
CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
Map<String, Tag> bukkitMap = bukkit.getValue();
String name =
(String) bukkitMap.get("lastKnownName").getValue();
long last = (long) bukkitMap.get("lastPlayed").getValue();
long first = (long) bukkitMap.get("firstPlayed").getValue();
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
ExpireManager.IMP.storeAccountAge(uuid, last - first);
}
toAdd.put(new StringWrapper(name), uuid);
}
}
} catch (Exception e) {
e.printStackTrace();
PlotSquared.debug(Captions.PREFIX + "Invalid playerdata: " + current);
}
}
}
add(toAdd);
if (all.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
} else {
PlotSquared.debug(
"Failed to cache: " + all.size() + " uuids - slowly processing all files");
}
}
HashSet<String> worlds1 = Sets.newHashSet(world, "world");
HashSet<UUID> uuids = new HashSet<>();
HashSet<String> names = new HashSet<>();
File playerDataFolder = null;
for (String worldName : worlds1) {
// Getting UUIDs
playerDataFolder = new File(container, worldName + File.separator + "playerdata");
String[] dat = playerDataFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (Exception ignored) {
PlotSquared.debug(Captions.PREFIX + "Invalid PlayerData: " + current);
}
}
break;
}
// Getting names
File playersFolder = new File(worldName + File.separator + "players");
dat = playersFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
break;
}
}
for (UUID uuid : uuids) {
try {
File file =
new File(playerDataFolder + File.separator + uuid.toString() + ".dat");
if (!file.exists()) {
continue;
}
CompoundTag compound = (CompoundTag) readTag(file);
if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\"");
} else {
Map<String, Tag> compoundMap = compound.getValue();
CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
Map<String, Tag> bukkitMap = bukkit.getValue();
String name = (String) bukkitMap.get("lastKnownName").getValue();
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
long last = (long) bukkitMap.get("lastPlayed").getValue();
long first = (long) bukkitMap.get("firstPlayed").getValue();
if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
.equals(name)) {
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
} else {
long most = (long) compoundMap.get("UUIDMost").getValue();
long least = (long) compoundMap.get("UUIDLeast").getValue();
uuid = new UUID(most, least);
}
}
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
ExpireManager.IMP.storeAccountAge(uuid, last - first);
}
toAdd.put(wrap, uuid);
}
}
} catch (Exception ignored) {
PlotSquared.debug(
Captions.PREFIX + "&6Invalid PlayerData: " + uuid.toString() + ".dat");
}
}
for (String name : names) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
StringWrapper nameWrap = new StringWrapper(name);
toAdd.put(nameWrap, uuid);
}
if (getUUIDMap().isEmpty()) {
for (OfflinePlotPlayer offlinePlotPlayer : FileUUIDHandler.this.uuidWrapper
.getOfflinePlayers()) {
long last = offlinePlotPlayer.getLastPlayed();
if (last != 0) {
String name = offlinePlotPlayer.getName();
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(offlinePlotPlayer);
if (toAdd.containsValue(uuid)) {
StringWrapper duplicate = toAdd.inverse().get(uuid);
PlotSquared.debug(
"The UUID: " + uuid.toString() + " is already mapped to "
+ duplicate
+ "\n It cannot be added to the Map with a key of " + wrap);
}
toAdd.putIfAbsent(wrap, uuid);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
}
}
}
}
add(toAdd);
if (whenDone != null) {
whenDone.run();
}
});
return true;
}
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
TaskManager.runTaskAsync(() -> {
ifFetch.value = FileUUIDHandler.this.uuidWrapper.getUUID(name);
TaskManager.runTask(ifFetch);
});
}
}

View File

@ -1,131 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util.uuid;
import com.google.common.base.Charsets;
import com.google.common.collect.BiMap;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
public class OfflineUUIDWrapper extends UUIDWrapper {
private final Object[] arg = new Object[0];
private Method getOnline = null;
public OfflineUUIDWrapper() {
try {
this.getOnline = Server.class.getMethod("getOnlinePlayers");
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
@NotNull @Override public UUID getUUID(PlotPlayer player) {
return UUID
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
}
@Override public UUID getUUID(OfflinePlotPlayer player) {
return UUID
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
}
public UUID getUUID(OfflinePlayer player) {
return UUID
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
}
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) {
BiMap<UUID, StringWrapper> map = UUIDHandler.getUuidMap().inverse();
String name = null;
if (map.containsKey(uuid)) {
name = map.get(uuid).value;
}
if (name != null) {
OfflinePlayer op = Bukkit.getOfflinePlayer(name);
if (op.hasPlayedBefore()) {
return new BukkitOfflinePlayer(op);
}
}
for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
if (getUUID(player).equals(uuid)) {
return new BukkitOfflinePlayer(player);
}
}
return null;
}
public Player[] getOnlinePlayers() {
if (this.getOnline == null) {
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[0]);
}
try {
Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
if (players instanceof Player[]) {
return (Player[]) players;
} else {
@SuppressWarnings("unchecked") Collection<? extends Player> p =
(Collection<? extends Player>) players;
return p.toArray(new Player[0]);
}
} catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ignored) {
PlotSquared.debug("Failed to resolve online players");
this.getOnline = null;
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[0]);
}
}
@Override public UUID getUUID(String name) {
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
}
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
return Arrays.stream(ops).map(BukkitOfflinePlayer::new).toArray(BukkitOfflinePlayer[]::new);
}
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
}
}

View File

@ -1,270 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util.uuid;
import com.google.common.collect.HashBiMap;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.database.SQLite;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.plotsquared.core.util.uuid.UUIDHandlerImplementation;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class SQLUUIDHandler extends UUIDHandlerImplementation {
final int MAX_REQUESTS = 500;
private final String PROFILE_URL =
"https://sessionserver.mojang.com/session/minecraft/profile/";
private final JSONParser jsonParser = new JSONParser();
private final SQLite sqlite;
public SQLUUIDHandler(UUIDWrapper wrapper) {
super(wrapper);
this.sqlite =
new SQLite(MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "usercache.db"));
try {
this.sqlite.openConnection();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
try (PreparedStatement stmt = getConnection().prepareStatement(
"CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid, username))")) {
stmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
startCaching(null);
}
private Connection getConnection() {
synchronized (this.sqlite) {
return this.sqlite.getConnection();
}
}
@Override public boolean startCaching(final Runnable whenDone) {
if (!super.startCaching(whenDone)) {
return false;
}
TaskManager.runTaskAsync(() -> {
try {
HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<>());
try (PreparedStatement statement = getConnection()
.prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
StringWrapper username = new StringWrapper(resultSet.getString("username"));
UUID uuid = UUID.fromString(resultSet.getString("uuid"));
toAdd.put(new StringWrapper(username.value), uuid);
}
}
add(toAdd);
// This should be called as long as there are some unknown plots
final ArrayDeque<UUID> toFetch = new ArrayDeque<>();
for (UUID u : UUIDHandler.getAllUUIDS()) {
if (!uuidExists(u)) {
toFetch.add(u);
}
}
if (toFetch.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
}
FileUUIDHandler fileHandler = new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
fileHandler.startCaching(() -> {
// If the file based UUID handler didn't cache it, then we can't cache offline mode
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
if (Settings.UUID.OFFLINE) {
if (whenDone != null) {
whenDone.run();
}
return;
}
TaskManager.runTaskAsync(() -> {
while (!toFetch.isEmpty()) {
try {
for (int i = 0; i < Math.min(MAX_REQUESTS, toFetch.size()); i++) {
UUID uuid = toFetch.pop();
HttpURLConnection connection = (HttpURLConnection) new URL(
SQLUUIDHandler.this.PROFILE_URL + uuid.toString()
.replace("-", "")).openConnection();
try (InputStream con = connection.getInputStream()) {
InputStreamReader reader = new InputStreamReader(con);
JSONObject response =
(JSONObject) SQLUUIDHandler.this.jsonParser
.parse(reader);
String name = (String) response.get("name");
if (name != null) {
add(new StringWrapper(name), uuid);
}
}
connection.disconnect();
}
} catch (IOException | ParseException e) {
PlotSquared.debug(
"Invalid response from Mojang: Some UUIDs will be cached later. (`unknown` until then or player joins)");
}
try {
//Mojang allows requests every 10 minutes according to https://wiki.vg/Mojang_API
//15 Minutes is chosen here since system timers are not always precise
//and it should provide enough time where Mojang won't block requests.
TimeUnit.MINUTES.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
if (whenDone != null) {
whenDone.run();
}
});
});
} catch (SQLException e) {
throw new SQLUUIDHandlerException("Couldn't select :s", e);
}
});
return true;
}
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
PlotSquared.debug(Captions.PREFIX + "UUID for '" + name
+ "' was null. We'll cache this from the Mojang servers!");
if (ifFetch == null) {
return;
}
TaskManager.runTaskAsync(() -> {
try {
URL url = new URL(SQLUUIDHandler.this.PROFILE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
String body = JSONArray.toJSONString(Collections.singletonList(name));
OutputStream stream = connection.getOutputStream();
stream.write(body.getBytes());
stream.flush();
stream.close();
JSONArray array = (JSONArray) SQLUUIDHandler.this.jsonParser
.parse(new InputStreamReader(connection.getInputStream()));
JSONObject jsonProfile = (JSONObject) array.get(0);
String id = (String) jsonProfile.get("id");
String name1 = (String) jsonProfile.get("name");
ifFetch.value = UUID.fromString(
id.substring(0, 8) + '-' + id.substring(8, 12) + '-' + id.substring(12, 16)
+ '-' + id.substring(16, 20) + '-' + id.substring(20, 32));
} catch (IOException | ParseException e) {
e.printStackTrace();
}
TaskManager.runTask(ifFetch);
});
}
@Override public void handleShutdown() {
super.handleShutdown();
try {
getConnection().close();
} catch (SQLException e) {
throw new SQLUUIDHandlerException("Couldn't close database connection", e);
}
}
/**
* This is useful for name changes
*/
@Override public void rename(final UUID uuid, final StringWrapper name) {
super.rename(uuid, name);
TaskManager.runTaskAsync(() -> {
try (PreparedStatement statement = getConnection()
.prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?")) {
statement.setString(1, name.value);
statement.setString(2, uuid.toString());
statement.execute();
PlotSquared.debug(
Captions.PREFIX + "Name change for '" + uuid + "' to '" + name.value + '\'');
} catch (SQLException e) {
e.printStackTrace();
}
});
}
@Override public boolean add(final StringWrapper name, final UUID uuid) {
// Ignoring duplicates
if (super.add(name, uuid)) {
TaskManager.runTaskAsync(() -> {
try (PreparedStatement statement = getConnection()
.prepareStatement("REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)")) {
statement.setString(1, uuid.toString());
statement.setString(2, name.toString());
statement.execute();
PlotSquared
.debug(Captions.PREFIX + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
return false;
}
private static class SQLUUIDHandlerException extends RuntimeException {
SQLUUIDHandlerException(String s, Throwable c) {
super("SQLUUIDHandler caused an exception: " + s, c);
}
}
}

View File

@ -0,0 +1,85 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import net.luckperms.api.model.user.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.alpenblock.bungeeperms.BungeePerms;
import net.alpenblock.bungeeperms.io.UUIDPlayerDB;
/**
* UUID service that uses the BungeePerms API
*/
public class BungeePermsUUIDService implements UUIDService {
private final BungeePerms bp;
public BungeePermsUUIDService() {
final RegisteredServiceProvider<BungeePerms> provider = Bukkit.getServicesManager().getRegistration(BungeePerms.class);
if (provider != null) {
this.bp = provider.getProvider();
} else {
throw new IllegalStateException("BungeePerms is not available");
}
}
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> mappings = new ArrayList<>(uuids.size());
final UUIDPlayerDB uuiddb = BungeePerms.getInstance().getPermissionsManager().getUUIDPlayerDB();
for (final UUID uuid : uuids) {
try {
final String username = uuiddb.getPlayerName(uuid);
if (username != null) {
mappings.add(new UUIDMapping(uuid, username));
}
} catch (final Exception ignored) {}
}
return mappings;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> mappings = new ArrayList<>(usernames.size());
final UUIDPlayerDB uuiddb = BungeePerms.getInstance().getPermissionsManager().getUUIDPlayerDB();
for (final String username : usernames) {
try {
final UUID uuid = uuiddb.getUUID(username);
if (username != null) {
mappings.add(new UUIDMapping(uuid, username));
}
} catch (final Exception ignored) {}
}
return mappings;
}
}

View File

@ -0,0 +1,70 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
/**
* UUID service using the EssentialsX API
*/
public class EssentialsUUIDService implements UUIDService {
private final Essentials essentials;
public EssentialsUUIDService() {
this.essentials = Essentials.getPlugin(Essentials.class);
}
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
return Collections.emptyList();
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> mappings = new ArrayList<>(usernames.size());
for (final String username : usernames) {
try {
final User user = essentials.getUser(username);
if (user != null) {
final UUID uuid = user.getConfigUUID();
if (uuid != null) {
mappings.add(new UUIDMapping(uuid, username));
}
}
} catch (final Exception ignored){}
}
return mappings;
}
}

View File

@ -0,0 +1,84 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.model.user.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* UUID service that uses the LuckPerms API
*/
public class LuckPermsUUIDService implements UUIDService {
private final LuckPerms luckPerms;
public LuckPermsUUIDService() {
final RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
this.luckPerms = provider.getProvider();
} else {
throw new IllegalStateException("LuckPerms not available");
}
}
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> mappings = new ArrayList<>(uuids.size());
final UserManager userManager = this.luckPerms.getUserManager();
for (final UUID uuid : uuids) {
try {
final String username = userManager.lookupUsername(uuid).get();
if (username != null) {
mappings.add(new UUIDMapping(uuid, username));
}
} catch (final Exception ignored) {}
}
return mappings;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> mappings = new ArrayList<>(usernames.size());
final UserManager userManager = this.luckPerms.getUserManager();
for (final String username : usernames) {
try {
final UUID uuid = userManager.lookupUniqueId(username).get();
if (username != null) {
mappings.add(new UUIDMapping(uuid, username));
}
} catch (final Exception ignored) {}
}
return mappings;
}
}

View File

@ -0,0 +1,85 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.google.common.base.Charsets;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
/**
* UUID service that use {@link org.bukkit.OfflinePlayer offline players}
*/
public class OfflinePlayerUUIDService implements UUIDService {
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
if (Settings.UUID.FORCE_LOWERCASE || Bukkit.getWorlds().isEmpty()) {
return Collections.emptyList(); // This is useless now
}
final List<UUIDMapping> wrappers = new ArrayList<>(uuids.size());
for (final UUID uuid : uuids) {
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
try {
if (offlinePlayer.hasPlayedBefore()) {
wrappers.add(new UUIDMapping(uuid, offlinePlayer.getName()));
}
} catch (final Exception ignored) {} /* This can be safely ignored. If this happens, it is
probably because it's called before the worlds have
been loaded. This is bad, but does not break anything */
}
return wrappers;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> wrappers = new ArrayList<>(usernames.size());
for (final String username : usernames) {
if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE) {
wrappers.add(new UUIDMapping(UUID.nameUUIDFromBytes(("OfflinePlayer:" +
username.toLowerCase()).getBytes(Charsets.UTF_8)), username));
} else {
wrappers.add(new UUIDMapping(UUID.nameUUIDFromBytes(("OfflinePlayer:" +
username).getBytes(Charsets.UTF_8)), username));
}
} else {
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(username);
if (offlinePlayer.hasPlayedBefore()) {
wrappers.add(new UUIDMapping(offlinePlayer.getUniqueId(), offlinePlayer.getName()));
}
}
}
return wrappers;
}
}

View File

@ -0,0 +1,65 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* UUID service that uses the Paper profile API
*/
public class PaperUUIDService implements UUIDService {
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> mappings = new ArrayList<>(uuids.size());
for (final UUID uuid : uuids) {
final PlayerProfile playerProfile = Bukkit.createProfile(uuid);
if ((playerProfile.isComplete() || playerProfile.completeFromCache()) && playerProfile.getId() != null) {
mappings.add(new UUIDMapping(playerProfile.getId(), playerProfile.getName()));
}
}
return mappings;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> mappings = new ArrayList<>(usernames.size());
for (final String username : usernames) {
final PlayerProfile playerProfile = Bukkit.createProfile(username);
if ((playerProfile.isComplete() || playerProfile.completeFromCache()) && playerProfile.getId() != null) {
mappings.add(new UUIDMapping(playerProfile.getId(), playerProfile.getName()));
}
}
return mappings;
}
}

View File

@ -0,0 +1,145 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.database.SQLite;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;
/**
* UUID service that uses the (legacy) SQL UUID cache
*/
public class SQLiteUUIDService implements UUIDService, Consumer<List<UUIDMapping>> {
private final SQLite sqlite;
public SQLiteUUIDService(final String fileName) {
this.sqlite =
new SQLite(MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), fileName));
try {
this.sqlite.openConnection();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
try (PreparedStatement stmt = getConnection().prepareStatement(
"CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid))")) {
stmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
private Connection getConnection() {
synchronized (this.sqlite) {
return this.sqlite.getConnection();
}
}
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> mappings = new ArrayList<>(uuids.size());
try (final PreparedStatement statement = getConnection()
.prepareStatement("SELECT `username` FROM `usercache` WHERE `uuid` = ?")) {
for (final UUID uuid : uuids) {
statement.setString(1, uuid.toString());
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
mappings.add(new UUIDMapping(uuid, resultSet.getString("username")));
}
}
}
} catch (final Exception e) {
e.printStackTrace();
}
return mappings;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull List<String> usernames) {
final List<UUIDMapping> mappings = new ArrayList<>(usernames.size());
try (final PreparedStatement statement = getConnection()
.prepareStatement("SELECT `uuid` FROM `usercache` WHERE `username` = ?")) {
for (final String username : usernames) {
statement.setString(1, username);
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
mappings.add(new UUIDMapping(UUID.fromString(resultSet.getString("uuid")),
username));
}
}
}
} catch (final Exception e) {
e.printStackTrace();
}
return mappings;
}
@Override public void accept(final List<UUIDMapping> uuidWrappers) {
try (final PreparedStatement statement = getConnection()
.prepareStatement("INSERT OR REPLACE INTO `usercache` (`uuid`, `username`) VALUES(?, ?)")) {
for (final UUIDMapping mapping : uuidWrappers) {
statement.setString(1, mapping.getUuid().toString());
statement.setString(2, mapping.getUsername());
statement.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* Read the entire cache at once
*
* @return All read mappings
*/
@NotNull public List<UUIDMapping> getAll() {
final List<UUIDMapping> mappings = new LinkedList<>();
try (final PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM `usercache`")) {
try (final ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
mappings.add(new UUIDMapping(UUID.fromString(resultSet.getString("uuid")), resultSet.getString("username")));
}
}
} catch (final Exception e) {
e.printStackTrace();
}
return mappings;
}
}

View File

@ -0,0 +1,90 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.uuid;
import com.google.common.util.concurrent.RateLimiter;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService;
import com.sk89q.squirrelid.Profile;
import com.sk89q.squirrelid.resolver.HttpRepositoryService;
import com.sk89q.squirrelid.resolver.ProfileService;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* UUID service using SquirrelID
*/
@SuppressWarnings("UnstableApiUsage")
public class SquirrelIdUUIDService implements UUIDService {
private final ProfileService profileService;
private final RateLimiter rateLimiter;
/**
* Create a new SquirrelID UUID service
*
* @param rateLimit Mojangs rate limit is 600 requests per 10 minutes.
* This parameter specifies how many of those requests
* we can use before our internal rate limit kicks in.
*/
public SquirrelIdUUIDService(final int rateLimit) {
this.profileService = HttpRepositoryService.forMinecraft();
// RateLimiter uses request per seconds. The constructor
// parameter rateLimit is requests per 600 seconds
this.rateLimiter = RateLimiter.create(rateLimit / 600.0D);
}
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> results = new ArrayList<>(uuids.size());
this.rateLimiter.acquire(uuids.size());
try {
for (final Profile profile : this.profileService.findAllById(uuids)) {
results.add(new UUIDMapping(profile.getUniqueId(), profile.getName()));
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return results;
}
@Override @NotNull public List<UUIDMapping> getUUIDs(@NotNull final List<String> usernames) {
final List<UUIDMapping> results = new ArrayList<>(usernames.size());
this.rateLimiter.acquire(usernames.size());
try {
for (final Profile profile : this.profileService.findAllByName(usernames)) {
results.add(new UUIDMapping(profile.getUniqueId(), profile.getName()));
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return results;
}
}

View File

@ -5,8 +5,8 @@ version: "${version}"
load: STARTUP load: STARTUP
description: "Easy, yet powerful Plot World generation and management." description: "Easy, yet powerful Plot World generation and management."
authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell] authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell]
website: https://github.com/IntellectualSites/ website: https://www.spigotmc.org/resources/77506/
softdepend: [Vault, PlaceholderAPI] softdepend: [Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms]
loadbefore: [MultiWorld, Multiverse-Core] loadbefore: [MultiWorld, Multiverse-Core]
depend: [WorldEdit] depend: [WorldEdit]
database: false database: false

View File

@ -1,5 +1,6 @@
repositories { repositories {
maven { url = "https://jitpack.io" } maven { url = "https://jitpack.io" }
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
} }
def textVersion = "3.0.2" def textVersion = "3.0.2"
@ -16,6 +17,7 @@ dependencies {
testAnnotationProcessor("org.projectlombok:lombok:1.18.8") testAnnotationProcessor("org.projectlombok:lombok:1.18.8")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72") implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72")
implementation("org.jetbrains:annotations:19.0.0") implementation("org.jetbrains:annotations:19.0.0")
implementation("org.khelekore:prtree:1.7.0-SNAPSHOT")
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8
@ -73,6 +75,7 @@ shadowJar {
include(dependency("net.kyori:text-serializer-gson:3.0.2")) include(dependency("net.kyori:text-serializer-gson:3.0.2"))
include(dependency("net.kyori:text-serializer-legacy:3.0.2")) include(dependency("net.kyori:text-serializer-legacy:3.0.2"))
include(dependency("net.kyori:text-serializer-plain:3.0.2")) include(dependency("net.kyori:text-serializer-plain:3.0.2"))
include(dependency("org.khelekore:prtree:1.7.0-SNAPSHOT"))
} }
relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate('net.kyori.text', 'com.plotsquared.formatting.text')
relocate("org.json", "com.plotsquared.json") { relocate("org.json", "com.plotsquared.json") {

View File

@ -9,7 +9,7 @@
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20190722</version> <version>20200518</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -92,6 +92,12 @@
<version>1.3.72</version> <version>1.3.72</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>org.khelekore</groupId>
<artifactId>prtree</artifactId>
<version>1.7.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -35,22 +35,29 @@ import com.plotsquared.core.util.ChatManager;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager; import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.logger.ILogger; import com.plotsquared.core.util.logger.ILogger;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandlerImplementation;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public interface IPlotMain extends ILogger { /**
* PlotSquared main utility class
*
* @param <P> Player type
*/
public interface IPlotMain<P> extends ILogger {
/** /**
* Logs a message to console. * Logs a message to console.
@ -79,7 +86,7 @@ public interface IPlotMain extends ILogger {
* @param player The player to convert to a PlotPlayer * @param player The player to convert to a PlotPlayer
* @return A PlotPlayer * @return A PlotPlayer
*/ */
PlotPlayer wrapPlayer(Object player); @Nullable PlotPlayer<P> wrapPlayer(Object player);
/** /**
* Completely shuts down the plugin. * Completely shuts down the plugin.
@ -168,11 +175,18 @@ public interface IPlotMain extends ILogger {
boolean initWorldEdit(); boolean initWorldEdit();
/** /**
* Gets the economy provider. * Gets the economy provider, if there is one
* *
* @return the PlotSquared economy manager * @return the PlotSquared economy manager
*/ */
EconHandler getEconomyHandler(); @Nullable EconHandler getEconomyHandler();
/**
* Gets the permission provider, if there is one
*
* @return the PlotSquared permission manager
*/
@Nullable PermHandler getPermissionHandler();
/** /**
* Gets the {@link QueueProvider} class. * Gets the {@link QueueProvider} class.
@ -220,12 +234,6 @@ public interface IPlotMain extends ILogger {
*/ */
void setGenerator(String world); void setGenerator(String world);
/**
* Gets the {@link UUIDHandlerImplementation} which will cache and
* provide UUIDs.
*/
UUIDHandlerImplementation initUUIDHandler();
/** /**
* Gets the {@link InventoryUtil} class (used for implementation specific * Gets the {@link InventoryUtil} class (used for implementation specific
* inventory guis). * inventory guis).
@ -285,6 +293,13 @@ public interface IPlotMain extends ILogger {
* *
* @return World manager * @return World manager
*/ */
@NotNull PlatformWorldManager getWorldManager(); @NotNull PlatformWorldManager<?> getWorldManager();
/**
* Get the player manager implementation for the platform
*
* @return Player manager
*/
@NotNull PlayerManager<? extends PlotPlayer<P>, ? extends P> getPlayerManager();
} }

View File

@ -53,6 +53,7 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.BlockBucket; import com.plotsquared.core.plot.BlockBucket;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotCluster; import com.plotsquared.core.plot.PlotCluster;
import com.plotsquared.core.plot.PlotFilter; import com.plotsquared.core.plot.PlotFilter;
@ -79,17 +80,18 @@ import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.logger.ILogger; import com.plotsquared.core.util.logger.ILogger;
import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler; import com.plotsquared.core.uuid.UUIDPipeline;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -116,6 +118,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -123,6 +126,7 @@ import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -137,9 +141,14 @@ public class PlotSquared {
private static final Set<Plot> EMPTY_SET = Collections.unmodifiableSet(Collections.emptySet()); private static final Set<Plot> EMPTY_SET = Collections.unmodifiableSet(Collections.emptySet());
private static PlotSquared instance; private static PlotSquared instance;
// Implementation // Implementation
public final IPlotMain IMP; public final IPlotMain<?> IMP;
// Current thread // Current thread
private final Thread thread; private final Thread thread;
// UUID pipelines
@Getter private final UUIDPipeline impromptuUUIDPipeline =
new UUIDPipeline(Executors.newCachedThreadPool());
@Getter private final UUIDPipeline backgroundUUIDPipeline =
new UUIDPipeline(Executors.newSingleThreadExecutor());
// WorldEdit instance // WorldEdit instance
public WorldEdit worldedit; public WorldEdit worldedit;
public File styleFile; public File styleFile;
@ -252,15 +261,6 @@ public class PlotSquared {
if (Settings.Enabled_Components.CHUNK_PROCESSOR) { if (Settings.Enabled_Components.CHUNK_PROCESSOR) {
this.IMP.registerChunkProcessor(); this.IMP.registerChunkProcessor();
} }
// create UUIDWrapper
UUIDHandler.implementation = this.IMP.initUUIDHandler();
if (Settings.Enabled_Components.UUID_CACHE) {
startUuidCatching();
} else {
// Start these separately
UUIDHandler.add(new StringWrapper("*"), DBFunc.EVERYONE);
startExpiryTasks();
}
// Create Event utility class // Create Event utility class
eventDispatcher = new EventDispatcher(); eventDispatcher = new EventDispatcher();
// create Hybrid utility class // create Hybrid utility class
@ -270,7 +270,8 @@ public class PlotSquared {
// create setup util class // create setup util class
SetupUtils.manager = this.IMP.initSetupUtils(); SetupUtils.manager = this.IMP.initSetupUtils();
// Set block // Set block
GlobalBlockQueue.IMP = new GlobalBlockQueue(IMP.initBlockQueue(), 1); GlobalBlockQueue.IMP =
new GlobalBlockQueue(IMP.initBlockQueue(), 1, Settings.QUEUE.TARGET_TIME);
GlobalBlockQueue.IMP.runTask(); GlobalBlockQueue.IMP.runTask();
// Set chunk // Set chunk
ChunkManager.manager = this.IMP.initChunkManager(); ChunkManager.manager = this.IMP.initChunkManager();
@ -303,8 +304,7 @@ public class PlotSquared {
} }
// Economy // Economy
if (Settings.Enabled_Components.ECONOMY) { if (Settings.Enabled_Components.ECONOMY) {
TaskManager TaskManager.runTask(() -> EconHandler.initializeEconHandler());
.runTask(() -> EconHandler.manager = PlotSquared.this.IMP.getEconomyHandler());
} }
if (Settings.Enabled_Components.COMPONENT_PRESETS) { if (Settings.Enabled_Components.COMPONENT_PRESETS) {
@ -385,11 +385,11 @@ public class PlotSquared {
return PlotSquared.instance; return PlotSquared.instance;
} }
public static IPlotMain imp() { @NotNull public static IPlotMain<?> imp() {
if (instance != null) { if (instance != null && instance.IMP != null) {
return instance.IMP; return instance.IMP;
} }
return null; throw new IllegalStateException("Plot main implementation is missing");
} }
/** /**
@ -427,23 +427,6 @@ public class PlotSquared {
} }
} }
private void startUuidCatching() {
TaskManager.runTaskLater(() -> {
debug("Starting UUID caching");
UUIDHandler.startCaching(() -> {
UUIDHandler.add(new StringWrapper("*"), DBFunc.EVERYONE);
forEachPlotRaw(plot -> {
if (plot.hasOwner() && plot.temp != -1) {
if (UUIDHandler.getName(plot.getOwnerAbs()) == null) {
UUIDHandler.implementation.unknown.add(plot.getOwnerAbs());
}
}
});
startExpiryTasks();
});
}, 20);
}
private void startExpiryTasks() { private void startExpiryTasks() {
if (Settings.Enabled_Components.PLOT_EXPIRY) { if (Settings.Enabled_Components.PLOT_EXPIRY) {
ExpireManager.IMP = new ExpireManager(); ExpireManager.IMP = new ExpireManager();
@ -640,17 +623,7 @@ public class PlotSquared {
* @return Set of base Plots * @return Set of base Plots
*/ */
public Set<Plot> getBasePlots() { public Set<Plot> getBasePlots() {
int size = getPlotCount(); return PlotQuery.newQuery().whereBasePlot().asSet();
final Set<Plot> result = new HashSet<>(size);
forEachPlotArea(value -> {
for (Plot plot : value.getPlots()) {
if (!plot.isBasePlot()) {
continue;
}
result.add(plot);
}
});
return Collections.unmodifiableSet(result);
} }
public List<Plot> sortPlotsByTemp(Collection<Plot> plots) { public List<Plot> sortPlotsByTemp(Collection<Plot> plots) {
@ -903,27 +876,25 @@ public class PlotSquared {
* *
* @param filters the filter * @param filters the filter
* @return a filtered set of plots * @return a filtered set of plots
* @deprecated Use {@link PlotQuery}
*/ */
public Set<Plot> getPlots(final PlotFilter... filters) { @Deprecated public Set<Plot> getPlots(final PlotFilter... filters) {
final HashSet<Plot> set = new HashSet<>(); final List<PlotArea> areas = new LinkedList<>();
forEachPlotArea(value -> { for (final PlotArea plotArea : this.getPlotAreas()) {
for (PlotFilter filter : filters) { for (final PlotFilter filter : filters) {
if (!filter.allowsArea(value)) { if (filter.allowsArea(plotArea)) {
return; areas.add(plotArea);
} }
} }
loop: }
for (Entry<PlotId, Plot> entry2 : value.getPlotEntries()) { return PlotQuery.newQuery().inAreas(areas).thatPasses(plot -> {
Plot plot = entry2.getValue(); for (final PlotFilter filter : filters) {
for (PlotFilter filter : filters) { if (!filter.allowsPlot(plot)) {
if (!filter.allowsPlot(plot)) { return false;
continue loop;
}
} }
set.add(plot);
} }
}); return true;
return set; }).asSet();
} }
/** /**
@ -966,7 +937,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlots(String world, String player) { public Set<Plot> getPlots(String world, String player) {
final UUID uuid = UUIDHandler.getUUID(player, null); final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, Settings.UUID.BLOCKING_TIMEOUT);
return getPlots(world, uuid); return getPlots(world, uuid);
} }
@ -978,7 +949,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlots(PlotArea area, String player) { public Set<Plot> getPlots(PlotArea area, String player) {
UUID uuid = UUIDHandler.getUUID(player, null); final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, Settings.UUID.BLOCKING_TIMEOUT);
return getPlots(area, uuid); return getPlots(area, uuid);
} }
@ -990,7 +961,7 @@ public class PlotSquared {
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(String world, PlotPlayer player) { public Set<Plot> getPlots(String world, PlotPlayer player) {
return getPlots(world, player.getUUID()); return PlotQuery.newQuery().inWorld(world).ownedBy(player).asSet();
} }
/** /**
@ -1001,7 +972,7 @@ public class PlotSquared {
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(PlotArea area, PlotPlayer player) { public Set<Plot> getPlots(PlotArea area, PlotPlayer player) {
return getPlots(area, player.getUUID()); return PlotQuery.newQuery().inArea(area).ownedBy(player).asSet();
} }
/** /**
@ -1012,10 +983,7 @@ public class PlotSquared {
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(String world, UUID uuid) { public Set<Plot> getPlots(String world, UUID uuid) {
final Set<Plot> plots = return PlotQuery.newQuery().inWorld(world).ownedBy(uuid).asSet();
getPlots(world).stream().filter(plot -> plot.hasOwner() && plot.isOwnerAbs(uuid))
.collect(Collectors.toSet());
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1026,13 +994,7 @@ public class PlotSquared {
* @return Set of plots * @return Set of plots
*/ */
public Set<Plot> getPlots(PlotArea area, UUID uuid) { public Set<Plot> getPlots(PlotArea area, UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().inArea(area).ownedBy(uuid).asSet();
for (Plot plot : getPlots(area)) {
if (plot.hasOwner() && plot.isOwnerAbs(uuid)) {
plots.add(plot);
}
}
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1047,9 +1009,7 @@ public class PlotSquared {
} }
public Collection<Plot> getPlots(String world) { public Collection<Plot> getPlots(String world) {
final Set<Plot> set = new HashSet<>(); return PlotQuery.newQuery().inWorld(world).asCollection();
forEachPlotArea(world, value -> set.addAll(value.getPlots()));
return set;
} }
/** /**
@ -1059,7 +1019,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlots(PlotPlayer player) { public Set<Plot> getPlots(PlotPlayer player) {
return getPlots(player.getUUID()); return PlotQuery.newQuery().ownedBy(player).asSet();
} }
public Collection<Plot> getPlots(PlotArea area) { public Collection<Plot> getPlots(PlotArea area) {
@ -1081,13 +1041,7 @@ public class PlotSquared {
* @return Set of Plot's owned by the player * @return Set of Plot's owned by the player
*/ */
public Set<Plot> getPlots(final UUID uuid) { public Set<Plot> getPlots(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).asSet();
forEachPlot(value -> {
if (value.isOwnerAbs(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
public boolean hasPlot(final UUID uuid) { public boolean hasPlot(final UUID uuid) {
@ -1096,13 +1050,7 @@ public class PlotSquared {
} }
public Set<Plot> getBasePlots(final UUID uuid) { public Set<Plot> getBasePlots(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).whereBasePlot().asSet();
forEachBasePlot(value -> {
if (value.isOwner(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1112,13 +1060,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlotsAbs(final UUID uuid) { public Set<Plot> getPlotsAbs(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).asSet();
forEachPlot(value -> {
if (value.isOwnerAbs(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1620,7 +1562,6 @@ public class PlotSquared {
// Close the connection // Close the connection
DBFunc.close(); DBFunc.close();
UUIDHandler.handleShutdown();
} catch (NullPointerException throwable) { } catch (NullPointerException throwable) {
throwable.printStackTrace(); throwable.printStackTrace();
PlotSquared.log("&cCould not close database connection!"); PlotSquared.log("&cCould not close database connection!");
@ -2014,6 +1955,23 @@ public class PlotSquared {
return Collections.unmodifiableSet(set); return Collections.unmodifiableSet(set);
} }
/**
* Check if the chunk uses vanilla/non-PlotSquared generation
*
* @param world World name
* @param chunkCoordinates Chunk coordinates
* @return True if the chunk uses non-standard generation, false if not
*/
public boolean isNonStandardGeneration(@NotNull final String world,
@NotNull final BlockVector2 chunkCoordinates) {
final Location location = new Location(world, chunkCoordinates.getBlockX() << 4, 64, chunkCoordinates.getBlockZ() << 4);
final PlotArea area = plotAreaManager.getApplicablePlotArea(location);
if (area == null) {
return true;
}
return area.getTerrain() != PlotAreaTerrainType.NONE;
}
public boolean isAugmented(@NonNull final String world) { public boolean isAugmented(@NonNull final String world) {
final PlotArea[] areas = plotAreaManager.getPlotAreas(world, null); final PlotArea[] areas = plotAreaManager.getPlotAreas(world, null);
return areas != null && (areas.length > 1 || areas[0].getType() != PlotAreaType.NORMAL); return areas != null && (areas.length > 1 || areas[0].getType() != PlotAreaType.NORMAL);
@ -2103,16 +2061,7 @@ public class PlotSquared {
*/ */
public Set<Plot> getPlotsByAlias(@Nullable final String alias, public Set<Plot> getPlotsByAlias(@Nullable final String alias,
@NonNull final String worldname) { @NonNull final String worldname) {
final Set<Plot> result = new HashSet<>(); return PlotQuery.newQuery().inWorld(worldname).withAlias(alias).asSet();
if (alias != null) {
for (final Plot plot : getPlots()) {
if (alias.equals(plot.getAlias()) && (worldname == null || worldname
.equals(plot.getWorldName()))) {
result.add(plot);
}
}
}
return Collections.unmodifiableSet(result);
} }
public Set<PlotArea> getPlotAreas(final String world, final CuboidRegion region) { public Set<PlotArea> getPlotAreas(final String world, final CuboidRegion region) {

View File

@ -38,8 +38,6 @@ import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.plotsquared.core.util.uuid.UUIDWrapper;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Collections; import java.util.Collections;
@ -60,9 +58,7 @@ import java.util.UUID;
* *
* @version 5 * @version 5
*/ */
@SuppressWarnings({"unused", "WeakerAccess"}) @SuppressWarnings({"unused", "WeakerAccess"}) @NoArgsConstructor public class PlotAPI {
@NoArgsConstructor
public class PlotAPI {
/** /**
* Gets all plots. * Gets all plots.
@ -140,17 +136,6 @@ public class PlotAPI {
return GlobalBlockQueue.IMP; return GlobalBlockQueue.IMP;
} }
/**
* UUIDWrapper class has basic methods for getting UUIDS. It's recommended
* to use the UUIDHandler class instead.
*
* @return UUIDWrapper
* @see UUIDWrapper
*/
public UUIDWrapper getUUIDWrapper() {
return UUIDHandler.getUUIDWrapper();
}
/** /**
* SchematicHandler class contains methods related to pasting, reading * SchematicHandler class contains methods related to pasting, reading
* and writing schematics. * and writing schematics.

View File

@ -142,7 +142,7 @@ public class PlayerBackupProfile implements BackupProfile {
} }
final List<Plot> plots = Collections.singletonList(plot); final List<Plot> plots = Collections.singletonList(plot);
final boolean result = SchematicHandler.manager.exportAll(plots, getBackupDirectory().toFile(), final boolean result = SchematicHandler.manager.exportAll(plots, getBackupDirectory().toFile(),
"%world%-%id%-%owner%-" + System.currentTimeMillis(), () -> "%world%-%id%-" + System.currentTimeMillis(), () ->
future.complete(new Backup(this, System.currentTimeMillis(), null))); future.complete(new Backup(this, System.currentTimeMillis(), null)));
if (!result) { if (!result) {
future.completeExceptionally(new RuntimeException("Failed to complete the backup")); future.completeExceptionally(new RuntimeException("Failed to complete the backup"));

View File

@ -32,13 +32,16 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "add", @CommandDeclaration(command = "add",
description = "Allow a user to build in a plot while the plot owner is online.", description = "Allow a user to build in a plot while the plot owner is online.",
@ -53,7 +56,7 @@ public class Add extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT); final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT);
@ -62,51 +65,73 @@ public class Add extends Command {
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST), .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST),
Captions.NO_PLOT_PERMS); Captions.NO_PLOT_PERMS);
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
final Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
checkTrue(!uuids.isEmpty(), Captions.INVALID_PLAYER, args[0]);
Iterator<UUID> iterator = uuids.iterator();
int size = plot.getTrusted().size() + plot.getMembers().size();
while (iterator.hasNext()) {
UUID uuid = iterator.next();
if (uuid == DBFunc.EVERYONE && !(
Permissions.hasPermission(player, Captions.PERMISSION_TRUST_EVERYONE) || Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST))) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid));
iterator.remove();
continue;
}
if (plot.isOwner(uuid)) {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid));
iterator.remove();
continue;
}
if (plot.getMembers().contains(uuid)) {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid));
iterator.remove();
continue;
}
size += plot.getTrusted().contains(uuid) ? 0 : 1;
}
checkTrue(!uuids.isEmpty(), null);
checkTrue(size <= plot.getArea().getMaxPlotMembers() || Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST),
Captions.PLOT_MAX_MEMBERS);
// Success
confirm.run(this, () -> {
for (UUID uuid : uuids) {
if (uuid != DBFunc.EVERYONE) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
}
plot.addMember(uuid);
PlotSquared.get().getEventDispatcher().callMember(player, plot, uuid, true);
MainUtil.sendMessage(player, Captions.MEMBER_ADDED);
}
}, null);
return CompletableFuture.completedFuture(true); final CompletableFuture<Boolean> future = new CompletableFuture<>();
MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> {
if (throwable != null) {
if (throwable instanceof TimeoutException) {
Captions.FETCHING_PLAYERS_TIMEOUT.send(player);
} else {
Captions.INVALID_PLAYER.send(player, args[0]);
}
future.completeExceptionally(throwable);
return;
} else {
try {
checkTrue(!uuids.isEmpty(), Captions.INVALID_PLAYER, args[0]);
Iterator<UUID> iterator = uuids.iterator();
int size = plot.getTrusted().size() + plot.getMembers().size();
while (iterator.hasNext()) {
UUID uuid = iterator.next();
if (uuid == DBFunc.EVERYONE && !(
Permissions.hasPermission(player, Captions.PERMISSION_TRUST_EVERYONE) || Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST))) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid));
iterator.remove();
continue;
}
if (plot.isOwner(uuid)) {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid));
iterator.remove();
continue;
}
if (plot.getMembers().contains(uuid)) {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid));
iterator.remove();
continue;
}
size += plot.getTrusted().contains(uuid) ? 0 : 1;
}
checkTrue(!uuids.isEmpty(), null);
checkTrue(size <= plot.getArea().getMaxPlotMembers() || Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST),
Captions.PLOT_MAX_MEMBERS);
// Success
confirm.run(this, () -> {
for (UUID uuid : uuids) {
if (uuid != DBFunc.EVERYONE) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
}
plot.addMember(uuid);
PlotSquared.get().getEventDispatcher().callMember(player, plot, uuid, true);
MainUtil.sendMessage(player, Captions.MEMBER_ADDED);
}
}, null);
} catch (final Throwable exception) {
future.completeExceptionally(exception);
return;
}
}
future.complete(true);
});
return future;
} }
@Override public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) {
return TabCompletions.completePlayers(String.join(",", args).trim(), Collections.emptyList());
}
} }

View File

@ -33,19 +33,26 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringWrapper; import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.uuid.UUIDHandler;
@CommandDeclaration(command = "setalias", import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "alias",
permission = "plots.alias", permission = "plots.alias",
description = "Set the plot name", description = "Set the plot name",
usage = "/plot alias <set|remove> <alias>", usage = "/plot alias <set|remove> <alias>",
aliases = {"alias", "sa", "name", "rename", "setname", "seta", "nameplot"}, aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"},
category = CommandCategory.SETTINGS, category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Alias extends SubCommand { public class Alias extends SubCommand {
private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) {};
private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) {};
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length == 0) { if (args.length == 0) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
@ -63,13 +70,11 @@ public class Alias extends SubCommand {
return false; return false;
} }
if (!plot.isOwner(player.getUUID())) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
boolean result = false; boolean result = false;
boolean owner = plot.isOwner(player.getUUID());
boolean permission;
boolean admin;
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "set": case "set":
if (args.length != 2) { if (args.length != 2) {
@ -77,17 +82,34 @@ public class Alias extends SubCommand {
return false; return false;
} }
if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET, false) permission = isPermitted(player, Captions.PERMISSION_ALIAS_SET)
|| canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE, false)) { || isPermitted(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE);
result = setAlias(player, plot, args[1]); admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_SET);
if (!admin && !owner) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
if (permission) { // is either admin or owner
setAlias(player, plot, args[1]);
return true;
} else { } else {
MainUtil.sendMessage(player, Captions.NO_PERMISSION); MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_ALIAS_SET.getTranslated());
} }
break; break;
case "remove": case "remove":
if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_REMOVE, true)) { permission = isPermitted(player, Captions.PERMISSION_ALIAS_REMOVE);
admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_REMOVE);
if (!admin && !owner) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
if (permission) {
result = removeAlias(player, plot); result = removeAlias(player, plot);
} else {
MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_ALIAS_REMOVE.getTranslated());
} }
break; break;
default: default:
@ -98,54 +120,58 @@ public class Alias extends SubCommand {
return result; return result;
} }
@Override
private boolean setAlias(PlotPlayer player, Plot plot, String alias) { public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
if (alias.isEmpty()) { final List<Command> commands = new ArrayList<>(2);
Captions.COMMAND_SYNTAX.send(player, getUsage()); if (args.length == 1) {
return false; if ("set".startsWith(args[0])) {
} commands.add(SET_COMMAND);
if (alias.length() >= 50) {
MainUtil.sendMessage(player, Captions.ALIAS_TOO_LONG);
return false;
}
if (alias.contains(" ")) {
Captions.NOT_VALID_VALUE.send(player);
return false;
}
if (MathMan.isInteger(alias)) {
Captions.NOT_VALID_VALUE.send(player);
return false;
}
for (Plot p : PlotSquared.get().getPlots(plot.getArea())) {
if (p.getAlias().equalsIgnoreCase(alias)) {
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
return false;
} }
if ("remove".startsWith(args[0])) {
commands.add(REMOVE_COMMAND);
}
return commands;
} }
if (UUIDHandler.nameExists(new StringWrapper(alias)) || PlotSquared.get() return Collections.emptySet();
.hasPlotArea(alias)) {
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
return false;
}
plot.setAlias(alias);
MainUtil.sendMessage(player,
Captions.ALIAS_SET_TO.getTranslated().replaceAll("%alias%", alias));
return true;
} }
private boolean removeAlias(PlotPlayer player, Plot plot) { private void setAlias(PlotPlayer player, Plot plot, String alias) {
if (alias.isEmpty()) {
Captions.COMMAND_SYNTAX.send(player, getUsage());
} else if (alias.length() >= 50) {
MainUtil.sendMessage(player, Captions.ALIAS_TOO_LONG);
} else if (alias.contains(" ")) {
Captions.NOT_VALID_VALUE.send(player);
} else if (MathMan.isInteger(alias)) {
Captions.NOT_VALID_VALUE.send(player);
} else {
if (PlotQuery.newQuery().inArea(plot.getArea())
.withAlias(alias)
.anyMatch()) {
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
return;
}
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} else if (uuid != null) {
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
} else {
plot.setAlias(alias);
MainUtil.sendMessage(player,
Captions.ALIAS_SET_TO.getTranslated().replaceAll("%alias%", alias));
}
}));
}
}
private boolean removeAlias(PlotPlayer<?> player, Plot plot) {
plot.setAlias(null); plot.setAlias(null);
MainUtil.sendMessage(player, Captions.ALIAS_REMOVED.getTranslated()); MainUtil.sendMessage(player, Captions.ALIAS_REMOVED.getTranslated());
return true; return true;
} }
private boolean canExecuteCommand(PlotPlayer player, Captions caption, boolean sendMessage) { private boolean isPermitted(PlotPlayer<?> player, Captions caption) {
if (!Permissions.hasPermission(player, caption)) { return Permissions.hasPermission(player, caption);
if (sendMessage) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION);
}
return false;
}
return true;
} }
} }

View File

@ -33,26 +33,41 @@ import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.generator.AugmentedUtils; import com.plotsquared.core.generator.AugmentedUtils;
import com.plotsquared.core.generator.HybridPlotWorld; import com.plotsquared.core.generator.HybridPlotWorld;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType; import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.setup.PlotAreaBuilder;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
@ -68,12 +83,140 @@ import java.util.Set;
confirmation = true) confirmation = true)
public class Area extends SubCommand { public class Area extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
if (args.length == 0) { if (args.length == 0) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return false; return false;
} }
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "single":
if (player instanceof ConsolePlayer) {
MainUtil.sendMessage(player, Captions.IS_CONSOLE);
return false;
}
if (!Permissions.hasPermission(player, Captions.PERMISSION_AREA_CREATE)) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_AREA_CREATE);
return false;
}
if (args.length < 2) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_NEEDS_NAME);
return false;
}
final PlotArea existingArea = PlotSquared.get().getPlotArea(player.getLocation().getWorld(), args[1]);
if (existingArea != null && existingArea.getId().equalsIgnoreCase(args[1])) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_NAME_TAKEN);
return false;
}
final LocalSession localSession = WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor());
if (localSession == null) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION);
return false;
}
Region playerSelectedRegion = null;
try {
playerSelectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld());
} catch (final Exception ignored) {}
if (playerSelectedRegion == null) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION);
return false;
}
if (playerSelectedRegion.getWidth() != playerSelectedRegion.getLength()) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_NOT_SQUARE);
return false;
}
if (PlotSquared.get().getPlotAreaManager().getPlotAreas(
Objects.requireNonNull(playerSelectedRegion.getWorld()).getName(), CuboidRegion.makeCuboid(playerSelectedRegion)).length != 0) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_OVERLAPPING);
}
// Alter the region
final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint();
final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint();
// Create a new selection that spans the entire vertical range of the world
final CuboidRegion selectedRegion = new CuboidRegion(playerSelectedRegion.getWorld(),
BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()),
BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ()));
// There's only one plot in the area...
final PlotId plotId = new PlotId(1, 1);
final HybridPlotWorld hybridPlotWorld = new HybridPlotWorld(player.getLocation().getWorld(), args[1],
Objects.requireNonNull(PlotSquared.imp()).getDefaultGenerator(), plotId, plotId);
// Plot size is the same as the region width
hybridPlotWorld.PLOT_WIDTH = hybridPlotWorld.SIZE = (short) selectedRegion.getWidth();
// We use a schematic generator
hybridPlotWorld.setTerrain(PlotAreaTerrainType.NONE);
// It is always a partial plot world
hybridPlotWorld.setType(PlotAreaType.PARTIAL);
// We save the schematic :D
hybridPlotWorld.PLOT_SCHEMATIC = true;
// Set the road width to 0
hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0;
// Set the plot height to the selection height
hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY();
// No sign plz
hybridPlotWorld.setAllowSigns(false);
final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator +
"GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator +
hybridPlotWorld.getId());
if (!parentFile.exists() && !parentFile.mkdirs()) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_COULD_NOT_MAKE_DIRECTORIES);
return false;
}
final File file = new File(parentFile, "plot.schem");
try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion);
final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(selectedRegion.getWorld(), -1);
final ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.getMinimumPoint());
forwardExtentCopy.setCopyingBiomes(true);
forwardExtentCopy.setCopyingEntities(true);
Operations.complete(forwardExtentCopy);
clipboardWriter.write(clipboard);
} catch (final Exception e) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_FAILED_TO_SAVE);
e.printStackTrace();
return false;
}
// Setup schematic
try {
hybridPlotWorld.setupSchematics();
} catch (final SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
}
// Calculate the offset
final BlockVector3 singlePos1 = selectedRegion.getMinimumPoint();
// Now the schematic is saved, which is wonderful!
PlotAreaBuilder singleBuilder = PlotAreaBuilder.ofPlotArea(hybridPlotWorld)
.plotManager(PlotSquared.imp().getPluginName())
.generatorName(PlotSquared.imp().getPluginName())
.maximumId(plotId)
.minimumId(plotId);
Runnable singleRun = () -> {
final String path =
"worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld.getId() + '-'
+ singleBuilder.minimumId() + '-' + singleBuilder.maximumId();
final int offsetX = singlePos1.getX();
final int offsetZ = singlePos1.getZ();
if (offsetX != 0) {
PlotSquared.get().worlds
.set(path + ".road.offset.x", offsetX);
}
if (offsetZ != 0) {
PlotSquared.get().worlds
.set(path + ".road.offset.z", offsetZ);
}
final String world = SetupUtils.manager.setupWorld(singleBuilder);
if (WorldUtil.IMP.isWorld(world)) {
PlotSquared.get().loadWorld(world, null);
MainUtil.sendMessage(player, Captions.SINGLE_AREA_CREATED);
} else {
MainUtil.sendMessage(player,
"An error occurred while creating the world: " + hybridPlotWorld
.getWorldName());
}
};
singleRun.run();
return true;
case "c": case "c":
case "setup": case "setup":
case "create": case "create":
@ -138,19 +281,14 @@ public class Area extends SubCommand {
.send(player, areas.iterator().next().toString()); .send(player, areas.iterator().next().toString());
return false; return false;
} }
final SetupObject object = new SetupObject(); PlotAreaBuilder builder = PlotAreaBuilder.ofPlotArea(area)
object.world = area.getWorldName(); .plotManager(PlotSquared.imp().getPluginName())
object.id = area.getId(); .generatorName(PlotSquared.imp().getPluginName())
object.terrain = area.getTerrain(); .minimumId(new PlotId(1, 1))
object.type = area.getType(); .maximumId(new PlotId(numX, numZ));
object.min = new PlotId(1, 1);
object.max = new PlotId(numX, numZ);
object.plotManager = PlotSquared.imp().getPluginName();
object.setupGenerator = PlotSquared.imp().getPluginName();
object.step = area.getSettingNodes();
final String path = final String path =
"worlds." + area.getWorldName() + ".areas." + area.getId() + '-' "worlds." + area.getWorldName() + ".areas." + area.getId() + '-'
+ object.min + '-' + object.max; + builder.minimumId() + '-' + builder.maximumId();
Runnable run = () -> { Runnable run = () -> {
if (offsetX != 0) { if (offsetX != 0) {
PlotSquared.get().worlds PlotSquared.get().worlds
@ -160,7 +298,7 @@ public class Area extends SubCommand {
PlotSquared.get().worlds PlotSquared.get().worlds
.set(path + ".road.offset.z", offsetZ); .set(path + ".road.offset.z", offsetZ);
} }
final String world = SetupUtils.manager.setupWorld(object); final String world = SetupUtils.manager.setupWorld(builder);
if (WorldUtil.IMP.isWorld(world)) { if (WorldUtil.IMP.isWorld(world)) {
PlotSquared.get().loadWorld(world, null); PlotSquared.get().loadWorld(world, null);
Captions.SETUP_FINISHED.send(player); Captions.SETUP_FINISHED.send(player);
@ -198,9 +336,9 @@ public class Area extends SubCommand {
} else { } else {
id = null; id = null;
} }
final SetupObject object = new SetupObject(); PlotAreaBuilder builder = new PlotAreaBuilder();
object.world = split[0]; builder.worldName(split[0]);
final HybridPlotWorld pa = new HybridPlotWorld(object.world, id, final HybridPlotWorld pa = new HybridPlotWorld(builder.worldName(), id,
PlotSquared.get().IMP.getDefaultGenerator(), null, null); PlotSquared.get().IMP.getDefaultGenerator(), null, null);
PlotArea other = PlotSquared.get().getPlotArea(pa.getWorldName(), id); PlotArea other = PlotSquared.get().getPlotArea(pa.getWorldName(), id);
if (other != null && Objects.equals(pa.getId(), other.getId())) { if (other != null && Objects.equals(pa.getId(), other.getId())) {
@ -262,13 +400,13 @@ public class Area extends SubCommand {
pa.setTerrain(PlotAreaTerrainType.fromString(pair[1]) pa.setTerrain(PlotAreaTerrainType.fromString(pair[1])
.orElseThrow(() -> new IllegalArgumentException( .orElseThrow(() -> new IllegalArgumentException(
pair[1] + " is not a valid terrain."))); pair[1] + " is not a valid terrain.")));
object.terrain = pa.getTerrain(); builder.terrainType(pa.getTerrain());
break; break;
case "type": case "type":
pa.setType(PlotAreaType.fromString(pair[1]).orElseThrow( pa.setType(PlotAreaType.fromString(pair[1]).orElseThrow(
() -> new IllegalArgumentException( () -> new IllegalArgumentException(
pair[1] + " is not a valid type."))); pair[1] + " is not a valid type.")));
object.type = pa.getType(); builder.plotAreaType(pa.getType());
break; break;
default: default:
Captions.COMMAND_SYNTAX.send(player, getCommandString() Captions.COMMAND_SYNTAX.send(player, getCommandString()
@ -290,9 +428,9 @@ public class Area extends SubCommand {
PlotSquared.get().worlds.getConfigurationSection(path); PlotSquared.get().worlds.getConfigurationSection(path);
pa.saveConfiguration(section); pa.saveConfiguration(section);
pa.loadConfiguration(section); pa.loadConfiguration(section);
object.plotManager = PlotSquared.imp().getPluginName(); builder.plotManager(PlotSquared.imp().getPluginName());
object.setupGenerator = PlotSquared.imp().getPluginName(); builder.generatorName(PlotSquared.imp().getPluginName());
String world = SetupUtils.manager.setupWorld(object); String world = SetupUtils.manager.setupWorld(builder);
if (WorldUtil.IMP.isWorld(world)) { if (WorldUtil.IMP.isWorld(world)) {
Captions.SETUP_FINISHED.send(player); Captions.SETUP_FINISHED.send(player);
player.teleport(WorldUtil.IMP.getSpawn(world), player.teleport(WorldUtil.IMP.getSpawn(world),
@ -327,9 +465,9 @@ public class Area extends SubCommand {
TeleportCause.COMMAND); TeleportCause.COMMAND);
} }
} else { } else {
object.terrain = PlotAreaTerrainType.NONE; builder.terrainType(PlotAreaTerrainType.NONE);
object.type = PlotAreaType.NORMAL; builder.plotAreaType(PlotAreaType.NORMAL);
SetupUtils.manager.setupWorld(object); SetupUtils.manager.setupWorld(builder);
player.teleport(WorldUtil.IMP.getSpawn(pa.getWorldName()), player.teleport(WorldUtil.IMP.getSpawn(pa.getWorldName()),
TeleportCause.COMMAND); TeleportCause.COMMAND);
} }

View File

@ -154,12 +154,12 @@ public class Auto extends SubCommand {
() -> autoClaimFromDatabase(player, area, plot.getId(), whenDone)); () -> autoClaimFromDatabase(player, area, plot.getId(), whenDone));
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
PlotArea plotarea = player.getApplicablePlotArea(); PlotArea plotarea = player.getApplicablePlotArea();
if (plotarea == null) { if (plotarea == null) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) { for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) {
if (EconHandler.manager if (EconHandler.getEconHandler()
.hasPermission(area.getWorldName(), player.getName(), "plots.auto")) { .hasPermission(area.getWorldName(), player.getName(), "plots.auto")) {
if (plotarea != null) { if (plotarea != null) {
plotarea = null; plotarea = null;
@ -253,18 +253,18 @@ public class Auto extends SubCommand {
return true; return true;
} }
} }
if (EconHandler.manager != null && plotarea.useEconomy()) { if (EconHandler.getEconHandler() != null && plotarea.useEconomy()) {
Expression<Double> costExp = plotarea.getPrices().get("claim"); Expression<Double> costExp = plotarea.getPrices().get("claim");
double cost = costExp.evaluate((double) (Settings.Limit.GLOBAL ? double cost = costExp.evaluate((double) (Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(plotarea.getWorldName()))); player.getPlotCount(plotarea.getWorldName())));
cost = (size_x * size_z) * cost; cost = (size_x * size_z) * cost;
if (cost > 0d) { if (cost > 0d) {
if (!force && EconHandler.manager.getMoney(player) < cost) { if (!force && EconHandler.getEconHandler().getMoney(player) < cost) {
sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost); sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
return true; return true;
} }
EconHandler.manager.withdrawMoney(player, cost); EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + ""); sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
} }
} }

View File

@ -70,7 +70,7 @@ public final class Backup extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 0 || !Arrays.asList("save", "list", "load") if (args.length == 0 || !Arrays.asList("save", "list", "load")

View File

@ -37,7 +37,6 @@ import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -55,11 +54,11 @@ public class Buy extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) { final RunnableVal2<Command, CommandResult> whenDone) {
check(EconHandler.manager, Captions.ECON_DISABLED); check(EconHandler.getEconHandler(), Captions.ECON_DISABLED);
final Plot plot; final Plot plot;
if (args.length != 0) { if (args.length != 0) {
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
@ -82,10 +81,10 @@ public class Buy extends Command {
// Success // Success
confirm.run(this, () -> { confirm.run(this, () -> {
Captions.REMOVED_BALANCE.send(player, price); Captions.REMOVED_BALANCE.send(player, price);
EconHandler.manager
.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.getOwnerAbs()), EconHandler.getEconHandler().depositMoney(PlotSquared.imp().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
price);
PlotPlayer owner = UUIDHandler.getPlayer(plot.getOwnerAbs()); PlotPlayer owner = PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs());
if (owner != null) { if (owner != null) {
Captions.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price); Captions.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price);
} }

View File

@ -50,7 +50,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
usage = "/plot caps") usage = "/plot caps")
public class Caps extends SubCommand { public class Caps extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, final String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, final String[] args) {
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (plot == null) { if (plot == null) {
return Captions.NOT_IN_PLOT.send(player); return Captions.NOT_IN_PLOT.send(player);

View File

@ -37,7 +37,7 @@ import com.plotsquared.core.util.MainUtil;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Chat extends SubCommand { public class Chat extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (player.getPlotAreaAbs().isForcingPlotChat()) { if (player.getPlotAreaAbs().isForcingPlotChat()) {
MainUtil.sendMessage(player, Captions.PLOT_CHAT_FORCED); MainUtil.sendMessage(player, Captions.PLOT_CHAT_FORCED);
return true; return true;

View File

@ -54,7 +54,7 @@ import com.plotsquared.core.util.task.TaskManager;
usage = "/plot claim") usage = "/plot claim")
public class Claim extends SubCommand { public class Claim extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
String schematic = null; String schematic = null;
if (args.length >= 1) { if (args.length >= 1) {
schematic = args[0]; schematic = args[0];
@ -105,14 +105,14 @@ public class Claim extends SubCommand {
} }
} }
} }
if ((EconHandler.manager != null) && area.useEconomy() && !force) { if ((EconHandler.getEconHandler() != null) && area.useEconomy() && !force) {
Expression<Double> costExr = area.getPrices().get("claim"); Expression<Double> costExr = area.getPrices().get("claim");
double cost = costExr.evaluate((double) currentPlots); double cost = costExr.evaluate((double) currentPlots);
if (cost > 0d) { if (cost > 0d) {
if (EconHandler.manager.getMoney(player) < cost) { if (EconHandler.getEconHandler().getMoney(player) < cost) {
return sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost); return sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
} }
EconHandler.manager.withdrawMoney(player, cost); EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + ""); sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
} }
} }

View File

@ -64,7 +64,7 @@ public class Clear extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
checkTrue(args.length == 0, Captions.COMMAND_SYNTAX, getUsage()); checkTrue(args.length == 0, Captions.COMMAND_SYNTAX, getUsage());

View File

@ -39,12 +39,12 @@ import com.plotsquared.core.plot.PlotCluster;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "cluster", @CommandDeclaration(command = "cluster",
aliases = "clusters", aliases = "clusters",
@ -54,7 +54,7 @@ import java.util.UUID;
description = "Manage a plot cluster") description = "Manage a plot cluster")
public class Cluster extends SubCommand { public class Cluster extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
// list, create, delete, resize, invite, kick, leave, helpers, tp, sethome // list, create, delete, resize, invite, kick, leave, helpers, tp, sethome
if (args.length == 0) { if (args.length == 0) {
@ -371,22 +371,29 @@ public class Cluster extends SubCommand {
return false; return false;
} }
} }
// check uuid
UUID uuid = UUIDHandler.getUUID(args[1], null); PlotSquared.get().getImpromptuUUIDPipeline()
if (uuid == null) { .getSingle(args[1], (uuid, throwable) -> {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[2]); if (throwable instanceof TimeoutException) {
return false; MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} } else if (throwable != null) {
if (!cluster.isAdded(uuid)) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[1]);
// add the user if not added } else {
cluster.invited.add(uuid); if (!cluster.isAdded(uuid)) {
DBFunc.setInvited(cluster, uuid); // add the user if not added
PlotPlayer player2 = UUIDHandler.getPlayer(uuid); cluster.invited.add(uuid);
if (player2 != null) { DBFunc.setInvited(cluster, uuid);
MainUtil.sendMessage(player2, Captions.CLUSTER_INVITED, cluster.getName());
} final PlotPlayer otherPlayer =
} PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid);
MainUtil.sendMessage(player, Captions.CLUSTER_ADDED_USER); if (otherPlayer != null) {
MainUtil.sendMessage(otherPlayer, Captions.CLUSTER_INVITED,
cluster.getName());
}
}
MainUtil.sendMessage(player, Captions.CLUSTER_ADDED_USER);
}
});
return true; return true;
} }
case "k": case "k":
@ -420,35 +427,43 @@ public class Cluster extends SubCommand {
} }
} }
// check uuid // check uuid
UUID uuid = UUIDHandler.getUUID(args[1], null); PlotSquared.get().getImpromptuUUIDPipeline()
if (uuid == null) { .getSingle(args[1], (uuid, throwable) -> {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[1]); if (throwable instanceof TimeoutException) {
return false; MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} } else if (throwable != null) {
// Can't kick if the player is yourself, the owner, or not added to the cluster MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[1]);
if (uuid.equals(player.getUUID()) || uuid.equals(cluster.owner) || !cluster } else {
.isAdded(uuid)) { // Can't kick if the player is yourself, the owner, or not added to the cluster
MainUtil.sendMessage(player, Captions.CANNOT_KICK_PLAYER, cluster.getName()); if (uuid.equals(player.getUUID()) || uuid.equals(cluster.owner)
return false; || !cluster.isAdded(uuid)) {
} MainUtil.sendMessage(player, Captions.CANNOT_KICK_PLAYER,
if (cluster.helpers.contains(uuid)) { cluster.getName());
cluster.helpers.remove(uuid); } else {
DBFunc.removeHelper(cluster, uuid); if (cluster.helpers.contains(uuid)) {
} cluster.helpers.remove(uuid);
cluster.invited.remove(uuid); DBFunc.removeHelper(cluster, uuid);
DBFunc.removeInvited(cluster, uuid); }
PlotPlayer player2 = UUIDHandler.getPlayer(uuid); cluster.invited.remove(uuid);
if (player2 != null) { DBFunc.removeInvited(cluster, uuid);
MainUtil.sendMessage(player2, Captions.CLUSTER_REMOVED, cluster.getName());
} final PlotPlayer player2 =
for (Plot plot : new ArrayList<>( PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid);
PlotSquared.get().getPlots(player2.getLocation().getWorld(), uuid))) { if (player2 != null) {
PlotCluster current = plot.getCluster(); MainUtil.sendMessage(player2, Captions.CLUSTER_REMOVED,
if (current != null && current.equals(cluster)) { cluster.getName());
plot.unclaim(); }
} for (Plot plot : new ArrayList<>(PlotSquared.get()
} .getPlots(player2.getLocation().getWorld(), uuid))) {
MainUtil.sendMessage(player2, Captions.CLUSTER_KICKED_USER); PlotCluster current = plot.getCluster();
if (current != null && current.equals(cluster)) {
plot.unclaim();
}
}
MainUtil.sendMessage(player2, Captions.CLUSTER_KICKED_USER);
}
}
});
return true; return true;
} }
case "quit": case "quit":
@ -529,24 +544,29 @@ public class Cluster extends SubCommand {
MainUtil.sendMessage(player, Captions.NOT_IN_CLUSTER); MainUtil.sendMessage(player, Captions.NOT_IN_CLUSTER);
return false; return false;
} }
UUID uuid = UUIDHandler.getUUID(args[2], null);
if (uuid == null) { PlotSquared.get().getImpromptuUUIDPipeline()
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[2]); .getSingle(args[2], (uuid, throwable) -> {
return false; if (throwable instanceof TimeoutException) {
} MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
if (args[1].equalsIgnoreCase("add")) { } else if (throwable != null) {
cluster.helpers.add(uuid); MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[2]);
DBFunc.setHelper(cluster, uuid); } else {
return MainUtil.sendMessage(player, Captions.CLUSTER_ADDED_HELPER); if (args[1].equalsIgnoreCase("add")) {
} cluster.helpers.add(uuid);
if (args[1].equalsIgnoreCase("remove")) { DBFunc.setHelper(cluster, uuid);
cluster.helpers.remove(uuid); MainUtil.sendMessage(player, Captions.CLUSTER_ADDED_HELPER);
DBFunc.removeHelper(cluster, uuid); } else if (args[1].equalsIgnoreCase("remove")) {
return MainUtil.sendMessage(player, Captions.CLUSTER_REMOVED_HELPER); cluster.helpers.remove(uuid);
} DBFunc.removeHelper(cluster, uuid);
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, MainUtil.sendMessage(player, Captions.CLUSTER_REMOVED_HELPER);
"/plot cluster helpers <add|remove> <player>"); } else {
return false; MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX,
"/plot cluster helpers <add|remove> <player>");
}
}
});
return true;
} }
case "spawn": case "spawn":
case "home": case "home":
@ -615,21 +635,31 @@ public class Cluster extends SubCommand {
} }
} }
String id = cluster.toString(); String id = cluster.toString();
String owner = UUIDHandler.getName(cluster.owner);
if (owner == null) { PlotSquared.get().getImpromptuUUIDPipeline()
owner = "unknown"; .getSingle(cluster.owner, (username, throwable) -> {
} if (throwable instanceof TimeoutException) {
String name = cluster.getName(); MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
String size = (cluster.getP2().x - cluster.getP1().x + 1) + "x" + ( } else {
cluster.getP2().y - cluster.getP1().y + 1); final String owner;
String rights = cluster.isAdded(player.getUUID()) + ""; if (username == null) {
String message = Captions.CLUSTER_INFO.getTranslated(); owner = "unknown";
message = message.replaceAll("%id%", id); } else {
message = message.replaceAll("%owner%", owner); owner = username;
message = message.replaceAll("%name%", name); }
message = message.replaceAll("%size%", size); String name = cluster.getName();
message = message.replaceAll("%rights%", rights); String size = (cluster.getP2().x - cluster.getP1().x + 1) + "x" + (
MainUtil.sendMessage(player, message); cluster.getP2().y - cluster.getP1().y + 1);
String rights = cluster.isAdded(player.getUUID()) + "";
String message = Captions.CLUSTER_INFO.getTranslated();
message = message.replaceAll("%id%", id);
message = message.replaceAll("%owner%", owner);
message = message.replaceAll("%name%", name);
message = message.replaceAll("%size%", size);
message = message.replaceAll("%rights%", rights);
MainUtil.sendMessage(player, message);
}
});
return true; return true;
} }
case "sh": case "sh":

View File

@ -32,15 +32,15 @@ import com.plotsquared.core.util.task.TaskManager;
public class CmdConfirm { public class CmdConfirm {
public static CmdInstance getPending(PlotPlayer player) { public static CmdInstance getPending(PlotPlayer<?> player) {
return player.getMeta("cmdConfirm"); return player.getMeta("cmdConfirm");
} }
public static void removePending(PlotPlayer player) { public static void removePending(PlotPlayer<?> player) {
player.deleteMeta("cmdConfirm"); player.deleteMeta("cmdConfirm");
} }
public static void addPending(final PlotPlayer player, String commandStr, public static void addPending(final PlotPlayer<?> player, String commandStr,
final Runnable runnable) { final Runnable runnable) {
removePending(player); removePending(player);
if (commandStr != null) { if (commandStr != null) {

View File

@ -37,6 +37,8 @@ import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -104,7 +106,7 @@ public abstract class Command {
&& types[4] == RunnableVal2.class) { && types[4] == RunnableVal2.class) {
Command tmp = new Command(this, true) { Command tmp = new Command(this, true) {
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
try { try {
@ -298,7 +300,7 @@ public abstract class Command {
* @return CompletableFuture true if the command executed fully, false in * @return CompletableFuture true if the command executed fully, false in
* any other case * any other case
*/ */
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 0 || args[0] == null) { if (args.length == 0 || args[0] == null) {
@ -603,6 +605,10 @@ public abstract class Command {
return object; return object;
} }
@SneakyThrows protected static void sneakyThrow(@NotNull final Throwable throwable) {
throw throwable;
}
public enum CommandResult { public enum CommandResult {
FAILURE, SUCCESS FAILURE, SUCCESS
} }

View File

@ -25,6 +25,7 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@ -33,11 +34,9 @@ import com.plotsquared.core.plot.comment.CommentManager;
import com.plotsquared.core.plot.comment.PlotComment; import com.plotsquared.core.plot.comment.PlotComment;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import java.util.Map.Entry;
@CommandDeclaration(command = "comment", @CommandDeclaration(command = "comment",
aliases = {"msg"}, aliases = {"msg"},
@ -47,7 +46,7 @@ import java.util.Map.Entry;
permission = "plots.comment") permission = "plots.comment")
public class Comment extends SubCommand { public class Comment extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length < 2) { if (args.length < 2) {
sendMessage(player, Captions.COMMENT_SYNTAX, sendMessage(player, Captions.COMMENT_SYNTAX,
StringMan.join(CommentManager.inboxes.keySet(), "|")); StringMan.join(CommentManager.inboxes.keySet(), "|"));
@ -96,12 +95,13 @@ public class Comment extends SubCommand {
StringMan.join(CommentManager.inboxes.keySet(), "|")); StringMan.join(CommentManager.inboxes.keySet(), "|"));
return false; return false;
} }
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue(); for (final PlotPlayer pp : PlotSquared.imp().getPlayerManager().getPlayers()) {
if (pp.getAttribute("chatspy")) { if (pp.getAttribute("chatspy")) {
MainUtil.sendMessage(pp, "/plot comment " + StringMan.join(args, " ")); MainUtil.sendMessage(pp, "/plot comment " + StringMan.join(args, " "));
} }
} }
sendMessage(player, Captions.COMMENT_ADDED); sendMessage(player, Captions.COMMENT_ADDED);
return true; return true;
} }

View File

@ -54,7 +54,7 @@ public class Condense extends SubCommand {
public static boolean TASK = false; public static boolean TASK = false;
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
if (args.length != 2 && args.length != 3) { if (args.length != 2 && args.length != 3) {
MainUtil.sendMessage(player, getUsage()); MainUtil.sendMessage(player, getUsage());
return false; return false;

View File

@ -37,7 +37,7 @@ import com.plotsquared.core.util.task.TaskManager;
category = CommandCategory.INFO) category = CommandCategory.INFO)
public class Confirm extends SubCommand { public class Confirm extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
CmdInstance command = CmdConfirm.getPending(player); CmdInstance command = CmdConfirm.getPending(player);
if (command == null) { if (command == null) {
MainUtil.sendMessage(player, Captions.FAILED_CONFIRM); MainUtil.sendMessage(player, Captions.FAILED_CONFIRM);

View File

@ -44,7 +44,7 @@ import com.plotsquared.core.util.Permissions;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Continue extends SubCommand { public class Continue extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
Plot plot = player.getCurrentPlot(); Plot plot = player.getCurrentPlot();
if ((plot == null) || !plot.hasOwner()) { if ((plot == null) || !plot.hasOwner()) {
return !sendMessage(player, Captions.NOT_IN_PLOT); return !sendMessage(player, Captions.NOT_IN_PLOT);

View File

@ -41,7 +41,7 @@ import com.plotsquared.core.util.Permissions;
requiredType = RequiredType.NONE) requiredType = RequiredType.NONE)
public class Copy extends SubCommand { public class Copy extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot1 = location.getPlotAbs(); Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {

View File

@ -42,7 +42,7 @@ import com.plotsquared.core.util.MainUtil;
usage = "/plot createroadschematic") usage = "/plot createroadschematic")
public class CreateRoadSchematic extends SubCommand { public class CreateRoadSchematic extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot = location.getPlotAbs(); Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {

View File

@ -74,7 +74,7 @@ public class DatabaseCommand extends SubCommand {
}); });
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
if (args.length < 1) { if (args.length < 1) {
MainUtil.sendMessage(player, getUsage()); MainUtil.sendMessage(player, getUsage());
return false; return false;

View File

@ -34,8 +34,10 @@ import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.entity.EntityCategory; import com.plotsquared.core.util.entity.EntityCategory;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.uuid.UUIDMapping;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.Map; import java.util.Map;
@ -46,7 +48,7 @@ import java.util.Map;
permission = "plots.admin") permission = "plots.admin")
public class Debug extends SubCommand { public class Debug extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length > 0) { if (args.length > 0) {
if ("player".equalsIgnoreCase(args[0])) { if ("player".equalsIgnoreCase(args[0])) {
for (Map.Entry<String, Object> meta : player.getMeta().entrySet()) { for (Map.Entry<String, Object> meta : player.getMeta().entrySet()) {
@ -65,6 +67,18 @@ public class Debug extends SubCommand {
.currentThread().getName())); .currentThread().getName()));
return true; return true;
} }
if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) {
final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately();
MainUtil.sendMessage(player, String.format("There are %d cached UUIDs", mappings.size()));
return true;
}
if (args.length > 0 && "debug-players".equalsIgnoreCase(args[0])) {
MainUtil.sendMessage(player, "Player in debug mode: " );
for (final PlotPlayer<?> pp : PlotPlayer.getDebugModePlayers()) {
MainUtil.sendMessage(player, "- " + pp.getName());
}
return true;
}
if (args.length > 0 && "entitytypes".equalsIgnoreCase(args[0])) { if (args.length > 0 && "entitytypes".equalsIgnoreCase(args[0])) {
EntityCategories.init(); EntityCategories.init();
player.sendMessage(Captions.PREFIX.getTranslated() + "§cEntity Categories: "); player.sendMessage(Captions.PREFIX.getTranslated() + "§cEntity Categories: ");

View File

@ -42,7 +42,7 @@ public class DebugAllowUnsafe extends SubCommand {
public static final List<UUID> unsafeAllowed = new ArrayList<>(); public static final List<UUID> unsafeAllowed = new ArrayList<>();
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (unsafeAllowed.contains(player.getUUID())) { if (unsafeAllowed.contains(player.getUUID())) {
unsafeAllowed.remove(player.getUUID()); unsafeAllowed.remove(player.getUUID());

View File

@ -1,134 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.command;
import com.google.common.collect.BiMap;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.math.BlockVector2;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@CommandDeclaration(command = "debugclaimtest",
description =
"If you accidentally delete your database, this command will attempt to restore all plots based on the data from plot signs. "
+ "Execution time may vary",
category = CommandCategory.DEBUG,
requiredType = RequiredType.CONSOLE,
permission = "plots.debugclaimtest")
public class DebugClaimTest extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
if (args.length < 3) {
return !MainUtil.sendMessage(null,
"If you accidentally delete your database, this command will attempt to restore all plots based on the data from the "
+ "plot signs. \n\n&cMissing world arg /plot debugclaimtest {world} {PlotId min} {PlotId max}");
}
PlotArea area = PlotSquared.get().getPlotAreaByString(args[0]);
if (area == null || !WorldUtil.IMP.isWorld(area.getWorldName())) {
Captions.NOT_VALID_PLOT_WORLD.send(player, args[0]);
return false;
}
PlotId min, max;
try {
args[1].split(";");
args[2].split(";");
min = PlotId.fromString(args[1]);
max = PlotId.fromString(args[2]);
} catch (Exception ignored) {
return !MainUtil.sendMessage(player,
"&cInvalid min/max values. &7The values are to Plot IDs in the format &cX;Y &7where X;Y are the plot coords\nThe conversion "
+ "will only check the plots in the selected area.");
}
MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: &7Beginning sign to plot conversion. This may take a while...");
MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: Found an excess of 250,000 chunks. Limiting search radius... (~3.8 min)");
PlotManager manager = area.getPlotManager();
CompletableFuture.runAsync(() -> {
ArrayList<PlotId> ids = MainUtil.getPlotSelectionIds(min, max);
MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: " + ids.size() + " plot ids to check!");
for (PlotId id : ids) {
Plot plot = area.getPlotAbs(id);
if (plot.hasOwner()) {
MainUtil.sendMessage(player, " - &cDB Already contains: " + plot.getId());
continue;
}
Location location = manager.getSignLoc(plot);
BlockVector2 chunk = BlockVector2.at(location.getX() >> 4, location.getZ() >> 4);
ChunkManager.manager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> {
String[] lines = WorldUtil.IMP.getSignSynchronous(location);
if (lines != null) {
String line = lines[2];
if (line != null && line.length() > 2) {
line = line.substring(2);
BiMap<StringWrapper, UUID> map = UUIDHandler.getUuidMap();
UUID uuid = map.get(new StringWrapper(line));
if (uuid == null) {
for (Map.Entry<StringWrapper, UUID> stringWrapperUUIDEntry : map
.entrySet()) {
if (stringWrapperUUIDEntry.getKey().value.toLowerCase()
.startsWith(line.toLowerCase())) {
uuid = stringWrapperUUIDEntry.getValue();
break;
}
}
}
if (uuid == null) {
uuid = UUIDHandler.getUUID(line, null);
}
if (uuid != null) {
MainUtil.sendMessage(player,
" - &aFound plot: " + plot.getId() + " : " + line);
plot.setOwner(uuid);
MainUtil.sendMessage(player, " - &8Updated plot: " + plot.getId());
} else {
MainUtil.sendMessage(player,
" - &cInvalid PlayerName: " + plot.getId() + " : " + line);
}
}
}
}).join();
}
}).thenRun(() -> MainUtil.sendMessage(player, "&3Sign Block&8->&3Plot&8: Finished scan."));
return true;
}
}

View File

@ -35,7 +35,6 @@ import com.plotsquared.core.events.Result;
import com.plotsquared.core.generator.HybridUtils; import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -59,7 +58,6 @@ import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import javax.script.Bindings; import javax.script.Bindings;
@ -71,13 +69,10 @@ import javax.script.SimpleScriptContext;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@CommandDeclaration(command = "debugexec", @CommandDeclaration(command = "debugexec",
@ -171,8 +166,7 @@ public class DebugExec extends SubCommand {
this.scope.put("BlockManager", WorldUtil.IMP); this.scope.put("BlockManager", WorldUtil.IMP);
this.scope.put("SetupUtils", SetupUtils.manager); this.scope.put("SetupUtils", SetupUtils.manager);
this.scope.put("EventUtil", PlotSquared.get().getEventDispatcher()); this.scope.put("EventUtil", PlotSquared.get().getEventDispatcher());
this.scope.put("EconHandler", EconHandler.manager); this.scope.put("EconHandler", EconHandler.getEconHandler());
this.scope.put("UUIDHandler", UUIDHandler.implementation);
this.scope.put("DBFunc", DBFunc.dbManager); this.scope.put("DBFunc", DBFunc.dbManager);
this.scope.put("HybridUtils", HybridUtils.manager); this.scope.put("HybridUtils", HybridUtils.manager);
this.scope.put("IMP", PlotSquared.get().IMP); this.scope.put("IMP", PlotSquared.get().IMP);
@ -184,7 +178,7 @@ public class DebugExec extends SubCommand {
} }
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
List<String> allowed_params = Arrays List<String> allowed_params = Arrays
.asList("analyze", "calibrate-analysis", "remove-flag", "stop-expire", "start-expire", .asList("analyze", "calibrate-analysis", "remove-flag", "stop-expire", "start-expire",
"seen", "list-scripts", "start-rgar", "stop-rgar", "help", "addcmd", "runasync", "seen", "list-scripts", "start-rgar", "stop-rgar", "help", "addcmd", "runasync",
@ -301,27 +295,6 @@ public class DebugExec extends SubCommand {
} else { } else {
return MainUtil.sendMessage(player, "Plot expiry task already started"); return MainUtil.sendMessage(player, "Plot expiry task already started");
} }
case "seen":
if (args.length != 2) {
return MainUtil.sendMessage(player, "Use /plot debugexec seen <player>");
}
UUID uuid = UUIDHandler.getUUID(args[1], null);
if (uuid == null) {
return MainUtil.sendMessage(player, "Player not found: " + args[1]);
}
OfflinePlotPlayer op = UUIDHandler.getUUIDWrapper().getOfflinePlayer(uuid);
if (op == null || op.getLastPlayed() == 0) {
return MainUtil
.sendMessage(player, "Player hasn't connected before: " + args[1]);
}
Timestamp stamp = new Timestamp(op.getLastPlayed());
Date date = new Date(stamp.getTime());
MainUtil.sendMessage(player, "PLAYER: " + args[1]);
MainUtil.sendMessage(player, "UUID: " + uuid);
MainUtil.sendMessage(player, "Object: " + date.toGMTString());
MainUtil.sendMessage(player, "GMT: " + date.toGMTString());
MainUtil.sendMessage(player, "Local: " + date.toLocaleString());
return true;
case "h": case "h":
case "he": case "he":
case "?": case "?":
@ -339,7 +312,7 @@ public class DebugExec extends SubCommand {
new Command(MainCommand.getInstance(), true, args[1].split("\\.")[0], null, new Command(MainCommand.getInstance(), true, args[1].split("\\.")[0], null,
RequiredType.NONE, CommandCategory.DEBUG) { RequiredType.NONE, CommandCategory.DEBUG) {
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, public CompletableFuture<Boolean> execute(PlotPlayer<?> player,
String[] args, RunnableVal3<Command, Runnable, Runnable> confirm, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
try { try {

View File

@ -27,6 +27,7 @@ package com.plotsquared.core.command;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
@ -35,7 +36,6 @@ import com.plotsquared.core.plot.world.SinglePlotAreaManager;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.io.File; import java.io.File;
import java.util.UUID; import java.util.UUID;
@ -52,7 +52,7 @@ public class DebugImportWorlds extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
// UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8)) // UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8))
@ -76,7 +76,8 @@ public class DebugImportWorlds extends Command {
if (name.length() > 16) { if (name.length() > 16) {
uuid = UUID.fromString(name); uuid = UUID.fromString(name);
} else { } else {
uuid = UUIDHandler.getUUID(name, null); Captions.FETCHING_PLAYER.send(player);
uuid = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(name, 60000L);
} }
if (uuid == null) { if (uuid == null) {
uuid = uuid =

View File

@ -37,7 +37,7 @@ import com.plotsquared.core.player.PlotPlayer;
requiredType = RequiredType.CONSOLE) requiredType = RequiredType.CONSOLE)
public class DebugLoadTest extends SubCommand { public class DebugLoadTest extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
PlotSquared.get().plots_tmp = DBFunc.getPlots(); PlotSquared.get().plots_tmp = DBFunc.getPlots();
return true; return true;
} }

View File

@ -35,7 +35,6 @@ import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
import com.plotsquared.core.util.net.IncendoPaster; import com.plotsquared.core.util.net.IncendoPaster;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import lombok.NonNull; import lombok.NonNull;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -72,7 +71,7 @@ public class DebugPaste extends SubCommand {
return content.toString(); return content.toString();
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
TaskManager.runTaskAsync(() -> { TaskManager.runTaskAsync(() -> {
try { try {
@ -90,7 +89,7 @@ public class DebugPaste extends SubCommand {
b.append("# Server Information\n"); b.append("# Server Information\n");
b.append("Server Version: ").append(PlotSquared.get().IMP.getServerImplementation()) b.append("Server Version: ").append(PlotSquared.get().IMP.getServerImplementation())
.append("\n"); .append("\n");
b.append("online_mode: ").append(UUIDHandler.getUUIDWrapper()).append(';') b.append("online_mode: ").append(!Settings.UUID.OFFLINE).append(';')
.append(!Settings.UUID.OFFLINE).append('\n'); .append(!Settings.UUID.OFFLINE).append('\n');
b.append("Plugins:"); b.append("Plugins:");
for (Map.Entry<Map.Entry<String, String>, Boolean> pluginInfo : PlotSquared for (Map.Entry<Map.Entry<String, String>, Boolean> pluginInfo : PlotSquared
@ -122,7 +121,7 @@ public class DebugPaste extends SubCommand {
b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n'); b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n');
b.append("# Okay :D Great. You are now ready to create your bug report!"); b.append("# Okay :D Great. You are now ready to create your bug report!");
b.append( b.append(
"\n# You can do so at https://github.com/IntellectualSites/PlotSquared/issues"); "\n# You can do so at https://issues.intellectualsites.com/projects/ps");
b.append("\n# or via our Discord at https://discord.gg/KxkjDVg"); b.append("\n# or via our Discord at https://discord.gg/KxkjDVg");
final IncendoPaster incendoPaster = new IncendoPaster("plotsquared"); final IncendoPaster incendoPaster = new IncendoPaster("plotsquared");

View File

@ -46,7 +46,7 @@ import java.util.Arrays;
public class DebugRoadRegen extends SubCommand { public class DebugRoadRegen extends SubCommand {
public static final String USAGE = "/plot debugroadregen <plot|region [height]>"; public static final String USAGE = "/plot debugroadregen <plot|region [height]>";
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length < 1) { if (args.length < 1) {
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, DebugRoadRegen.USAGE); MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, DebugRoadRegen.USAGE);
return false; return false;

View File

@ -41,7 +41,7 @@ import java.util.ArrayList;
description = "This command will force the recreation of all plots in the DB") description = "This command will force the recreation of all plots in the DB")
public class DebugSaveTest extends SubCommand { public class DebugSaveTest extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots()); ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots());
MainUtil.sendMessage(player, "&6Starting `DEBUGSAVETEST`"); MainUtil.sendMessage(player, "&6Starting `DEBUGSAVETEST`");
DBFunc.createPlotsAndData(plots, DBFunc.createPlotsAndData(plots,

View File

@ -53,7 +53,7 @@ public class Delete extends SubCommand {
// Note: To delete a specific plot use /plot <plot> delete // Note: To delete a specific plot use /plot <plot> delete
// The syntax also works with any command: /plot <plot> <command> // The syntax also works with any command: /plot <plot> <command>
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
final Plot plot = location.getPlotAbs(); final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
@ -86,11 +86,11 @@ public class Delete extends SubCommand {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
boolean result = plot.deletePlot(() -> { boolean result = plot.deletePlot(() -> {
plot.removeRunning(); plot.removeRunning();
if ((EconHandler.manager != null) && plotArea.useEconomy()) { if ((EconHandler.getEconHandler() != null) && plotArea.useEconomy()) {
Expression<Double> valueExr = plotArea.getPrices().get("sell"); Expression<Double> valueExr = plotArea.getPrices().get("sell");
double value = plots.size() * valueExr.evaluate((double) currentPlots); double value = plots.size() * valueExr.evaluate((double) currentPlots);
if (value > 0d) { if (value > 0d) {
EconHandler.manager.depositMoney(player, value); EconHandler.getEconHandler().depositMoney(player, value);
sendMessage(player, Captions.ADDED_BALANCE, String.valueOf(value)); sendMessage(player, Captions.ADDED_BALANCE, String.valueOf(value));
} }
} }

View File

@ -33,12 +33,14 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.uuid.UUIDHandler;
import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.gamemode.GameModes;
import java.util.Set; import java.util.Collection;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "deny", @CommandDeclaration(command = "deny",
aliases = {"d", "ban"}, aliases = {"d", "ban"},
@ -52,7 +54,7 @@ public class Deny extends SubCommand {
super(Argument.PlayerName); super(Argument.PlayerName);
} }
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot = location.getPlotAbs(); Plot plot = location.getPlotAbs();
@ -68,51 +70,55 @@ public class Deny extends SubCommand {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return true; return true;
} }
Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
if (uuids.isEmpty()) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
return false;
}
for (UUID uuid : uuids) {
if (uuid == DBFunc.EVERYONE && !(
Permissions.hasPermission(player, Captions.PERMISSION_DENY_EVERYONE) || Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_DENY))) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid));
continue;
}
if (plot.isOwner(uuid)) {
MainUtil.sendMessage(player, Captions.CANT_REMOVE_OWNER, MainUtil.getName(uuid));
return false;
}
if (plot.getDenied().contains(uuid)) { MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid)); if (throwable instanceof TimeoutException) {
return false; MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} } else if (throwable != null || uuids.isEmpty()) {
if (uuid != DBFunc.EVERYONE) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
plot.removeMember(uuid);
plot.removeTrusted(uuid);
}
plot.addDenied(uuid);
PlotSquared.get().getEventDispatcher().callDenied(player, plot, uuid, true);
if (!uuid.equals(DBFunc.EVERYONE)) {
handleKick(UUIDHandler.getPlayer(uuid), plot);
} else { } else {
for (PlotPlayer plotPlayer : plot.getPlayersInPlot()) { for (UUID uuid : uuids) {
// Ignore plot-owners if (uuid == DBFunc.EVERYONE && !(
if (plot.isAdded(plotPlayer.getUUID())) { Permissions.hasPermission(player, Captions.PERMISSION_DENY_EVERYONE) || Permissions
continue; .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_DENY))) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid));
} else if (plot.isOwner(uuid)) {
MainUtil.sendMessage(player, Captions.CANT_REMOVE_OWNER, MainUtil.getName(uuid));
return;
} else if (plot.getDenied().contains(uuid)) {
MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid));
return;
} else {
if (uuid != DBFunc.EVERYONE) {
plot.removeMember(uuid);
plot.removeTrusted(uuid);
}
plot.addDenied(uuid);
PlotSquared.get().getEventDispatcher().callDenied(player, plot, uuid, true);
if (!uuid.equals(DBFunc.EVERYONE)) {
handleKick(PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid), plot);
} else {
for (PlotPlayer plotPlayer : plot.getPlayersInPlot()) {
// Ignore plot-owners
if (plot.isAdded(plotPlayer.getUUID())) {
continue;
}
handleKick(plotPlayer, plot);
}
}
} }
handleKick(plotPlayer, plot);
} }
MainUtil.sendMessage(player, Captions.DENIED_ADDED);
} }
} });
if (!uuids.isEmpty()) {
MainUtil.sendMessage(player, Captions.DENIED_ADDED);
}
return true; return true;
} }
@Override public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) {
return TabCompletions.completePlayers(String.join(",", args).trim(), Collections.emptyList());
}
private void handleKick(PlotPlayer player, Plot plot) { private void handleKick(PlotPlayer player, Plot plot) {
if (player == null) { if (player == null) {
return; return;

View File

@ -35,7 +35,7 @@ import com.plotsquared.core.player.PlotPlayer;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Dislike extends SubCommand { public class Dislike extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
return Like.handleLike(player, args, false); return Like.handleLike(player, args, false);
} }

View File

@ -51,7 +51,7 @@ import com.plotsquared.core.util.task.RunnableVal;
requiredType = RequiredType.NONE) requiredType = RequiredType.NONE)
public class Done extends SubCommand { public class Done extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
final Plot plot = location.getPlotAbs(); final Plot plot = location.getPlotAbs();
if ((plot == null) || !plot.hasOwner()) { if ((plot == null) || !plot.hasOwner()) {

View File

@ -50,7 +50,7 @@ import java.net.URL;
permission = "plots.download") permission = "plots.download")
public class Download extends SubCommand { public class Download extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
String world = player.getLocation().getWorld(); String world = player.getLocation().getWorld();
if (!PlotSquared.get().hasPlotArea(world)) { if (!PlotSquared.get().hasPlotArea(world)) {
return !sendMessage(player, Captions.NOT_IN_PLOT_WORLD); return !sendMessage(player, Captions.NOT_IN_PLOT_WORLD);

View File

@ -207,7 +207,7 @@ public final class FlagCommand extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 0 || !Arrays if (args.length == 0 || !Arrays

View File

@ -26,6 +26,7 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
@ -35,10 +36,10 @@ import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "grant", @CommandDeclaration(command = "grant",
category = CommandCategory.CLAIMING, category = CommandCategory.CLAIMING,
@ -52,7 +53,7 @@ public class Grant extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
checkTrue(args.length >= 1 && args.length <= 2, Captions.COMMAND_SYNTAX, getUsage()); checkTrue(args.length >= 1 && args.length <= 2, Captions.COMMAND_SYNTAX, getUsage());
@ -69,43 +70,44 @@ public class Grant extends Command {
if (args.length > 2) { if (args.length > 2) {
break; break;
} }
final UUID uuid; MainUtil.getUUIDsFromString(args[1], (uuids, throwable) -> {
if (args.length == 2) { if (throwable instanceof TimeoutException) {
uuid = UUIDHandler.getUUIDFromString(args[1]); MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} else { } else if (throwable != null || uuids.size() != 1) {
uuid = player.getUUID(); MainUtil.sendMessage(player, Captions.INVALID_PLAYER);
} } else {
if (uuid == null) { final UUID uuid = uuids.toArray(new UUID[0])[0];
Captions.INVALID_PLAYER.send(player, args[1]); MainUtil.getPersistentMeta(uuid,
return CompletableFuture.completedFuture(false); "grantedPlots", new RunnableVal<byte[]>() {
} @Override public void run(byte[] array) {
MainUtil.getPersistentMeta(uuid, "grantedPlots", new RunnableVal<byte[]>() { if (arg0.equals("check")) { // check
@Override public void run(byte[] array) { int granted;
if (arg0.equals("check")) { // check if (array == null) {
int granted; granted = 0;
if (array == null) { } else {
granted = 0; granted = Ints.fromByteArray(array);
} else { }
granted = Ints.fromByteArray(array); Captions.GRANTED_PLOTS.send(player, granted);
} else { // add
int amount;
if (array == null) {
amount = 1;
} else {
amount = 1 + Ints.fromByteArray(array);
}
boolean replace = array != null;
String key = "grantedPlots";
byte[] rawData = Ints.toByteArray(amount);
PlotPlayer online = PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid);
if (online != null) {
online.setPersistentMeta(key, rawData);
} else {
DBFunc.addPersistentMeta(uuid, key, rawData, replace);
}
}
} }
Captions.GRANTED_PLOTS.send(player, granted); });
} else { // add
int amount;
if (array == null) {
amount = 1;
} else {
amount = 1 + Ints.fromByteArray(array);
}
boolean replace = array != null;
String key = "grantedPlots";
byte[] rawData = Ints.toByteArray(amount);
PlotPlayer online = UUIDHandler.getPlayer(uuid);
if (online != null) {
online.setPersistentMeta(key, rawData);
} else {
DBFunc.addPersistentMeta(uuid, key, rawData, replace);
}
}
} }
}); });
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);

View File

@ -52,7 +52,7 @@ public class Help extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
switch (args.length) { switch (args.length) {

View File

@ -86,7 +86,7 @@ public class Inbox extends SubCommand {
MainUtil.sendMessage(player, string.toString()); MainUtil.sendMessage(player, string.toString());
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NOT_IN_PLOT); sendMessage(player, Captions.NOT_IN_PLOT);

View File

@ -41,7 +41,7 @@ import com.plotsquared.core.util.task.RunnableVal;
category = CommandCategory.INFO) category = CommandCategory.INFO)
public class Info extends SubCommand { public class Info extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Plot plot; Plot plot;
String arg; String arg;
if (args.length > 0) { if (args.length > 0) {

View File

@ -33,12 +33,15 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "kick", @CommandDeclaration(command = "kick",
aliases = "k", aliases = "k",
@ -53,7 +56,7 @@ public class Kick extends SubCommand {
super(Argument.PlayerName); super(Argument.PlayerName);
} }
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot = location.getPlot(); Plot plot = location.getPlot();
if (plot == null) { if (plot == null) {
@ -64,57 +67,72 @@ public class Kick extends SubCommand {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false; return false;
} }
Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
if (uuids.isEmpty()) { MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); if (throwable instanceof TimeoutException) {
return false; MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} } else if (throwable != null || uuids.isEmpty()) {
Set<PlotPlayer> players = new HashSet<>(); MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
for (UUID uuid : uuids) { } else {
if (uuid == DBFunc.EVERYONE) { Set<PlotPlayer<?>> players = new HashSet<>();
for (PlotPlayer pp : plot.getPlayersInPlot()) { for (UUID uuid : uuids) {
if (pp == player || Permissions if (uuid == DBFunc.EVERYONE) {
.hasPermission(pp, Captions.PERMISSION_ADMIN_ENTRY_DENIED)) { for (PlotPlayer<?> pp : plot.getPlayersInPlot()) {
if (pp == player || Permissions
.hasPermission(pp, Captions.PERMISSION_ADMIN_ENTRY_DENIED)) {
continue;
}
players.add(pp);
}
continue; continue;
} }
players.add(pp); PlotPlayer<?> pp = PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid);
if (pp != null) {
players.add(pp);
}
} }
continue; players.remove(player); // Don't ever kick the calling player
} if (players.isEmpty()) {
PlotPlayer pp = UUIDHandler.getPlayer(uuid); MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
if (pp != null) { return;
players.add(pp); }
} for (PlotPlayer<?> player2 : players) {
} if (!plot.equals(player2.getCurrentPlot())) {
players.remove(player); // Don't ever kick the calling player MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
if (players.isEmpty()) { return;
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); }
return false; if (Permissions.hasPermission(player2, Captions.PERMISSION_ADMIN_ENTRY_DENIED)) {
} Captions.CANNOT_KICK_PLAYER.send(player, player2.getName());
for (PlotPlayer player2 : players) { return;
if (!plot.equals(player2.getCurrentPlot())) { }
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); Location spawn = WorldUtil.IMP.getSpawn(location.getWorld());
return false; Captions.YOU_GOT_KICKED.send(player2);
} if (plot.equals(spawn.getPlot())) {
if (Permissions.hasPermission(player2, Captions.PERMISSION_ADMIN_ENTRY_DENIED)) { Location newSpawn = WorldUtil.IMP
Captions.CANNOT_KICK_PLAYER.send(player, player2.getName()); .getSpawn(PlotSquared.get().getPlotAreaManager().getAllWorlds()[0]);
return false; if (plot.equals(newSpawn.getPlot())) {
} // Kick from server if you can't be teleported to spawn
Location spawn = WorldUtil.IMP.getSpawn(location.getWorld()); player2.kick(Captions.YOU_GOT_KICKED.getTranslated());
Captions.YOU_GOT_KICKED.send(player2); } else {
if (plot.equals(spawn.getPlot())) { player2.plotkick(newSpawn);
Location newSpawn = WorldUtil.IMP }
.getSpawn(PlotSquared.get().getPlotAreaManager().getAllWorlds()[0]); } else {
if (plot.equals(newSpawn.getPlot())) { player2.plotkick(spawn);
// Kick from server if you can't be teleported to spawn }
player2.kick(Captions.YOU_GOT_KICKED.getTranslated());
} else {
player2.plotkick(newSpawn);
} }
} else {
player2.plotkick(spawn);
} }
} });
return true; return true;
} }
@Override public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
if (plot == null) {
return Collections.emptyList();
}
return TabCompletions.completePlayersInPlot(plot, String.join(",", args).trim(),
Collections.singletonList(player.getName()));
}
} }

View File

@ -48,7 +48,7 @@ public class Leave extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT); final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT);

View File

@ -175,7 +175,7 @@ public class Like extends SubCommand {
return numLikes / (numLikes + numDislikes); return numLikes / (numLikes + numDislikes);
} }
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
return handleLike(player, args, true); return handleLike(player, args, true);
} }

View File

@ -26,13 +26,12 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.PlotSquared.SortType;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.Rating;
import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.ExpireManager;
import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.PriceFlag; import com.plotsquared.core.plot.flag.implementations.PriceFlag;
@ -43,26 +42,36 @@ import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.query.SortingStrategy;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.uuid.UUIDHandler; import com.plotsquared.core.uuid.UUIDMapping;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@CommandDeclaration(command = "list", @CommandDeclaration(command = "list",
aliases = {"l", "find", "search"}, aliases = {"l", "find", "search"},
description = "List plots", description = "List plots",
permission = "plots.list", permission = "plots.list",
category = CommandCategory.INFO, category = CommandCategory.INFO,
usage = "/plot list <forsale|mine|shared|world|top|all|unowned|unknown|player|world|done|fuzzy <search...>> [#]") usage = "/plot list <forsale|mine|shared|world|top|all|unowned|player|world|done|fuzzy <search...>> [#]")
public class ListCmd extends SubCommand { public class ListCmd extends SubCommand {
private String[] getArgumentList(PlotPlayer player) { private String[] getArgumentList(PlotPlayer player) {
List<String> args = new ArrayList<>(); List<String> args = new ArrayList<>();
if (EconHandler.manager != null && Permissions if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { .hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
args.add("forsale"); args.add("forsale");
} }
@ -84,9 +93,6 @@ public class ListCmd extends SubCommand {
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) {
args.add("unowned"); args.add("unowned");
} }
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) {
args.add("unknown");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) { if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) {
args.add("<player>"); args.add("<player>");
} }
@ -110,30 +116,58 @@ public class ListCmd extends SubCommand {
.toString(getArgumentList(player))); .toString(getArgumentList(player)));
} }
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length < 1) { if (args.length < 1) {
noArgs(player); noArgs(player);
return false; return false;
} }
int page = 0;
final int page;
if (args.length > 1) { if (args.length > 1) {
int tempPage = -1;
try { try {
page = Integer.parseInt(args[args.length - 1]); tempPage = Integer.parseInt(args[args.length - 1]);
--page; --tempPage;
if (page < 0) { if (tempPage < 0) {
page = 0; tempPage = 0;
} }
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
page = -1;
} }
page = tempPage;
} else {
page = 0;
} }
List<Plot> plots = null;
String world = player.getLocation().getWorld(); String world = player.getLocation().getWorld();
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
String arg = args[0].toLowerCase(); String arg = args[0].toLowerCase();
boolean sort = true; final boolean[] sort = new boolean[] {true};
final Consumer<PlotQuery> plotConsumer = query -> {
if (query == null) {
sendMessage(player, Captions.DID_YOU_MEAN,
new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"})
.getBestMatch());
return;
}
if (area != null) {
query.relativeToArea(area);
}
if (sort[0]) {
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
}
final List<Plot> plots = query.asList();
if (plots.isEmpty()) {
MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS);
return;
}
displayPlots(player, plots, 12, page, args);
};
switch (arg) { switch (arg) {
case "mine": case "mine":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) {
@ -141,8 +175,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_MINE); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_MINE);
return false; return false;
} }
sort = false; sort[0] = false;
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player)); plotConsumer.accept(PlotQuery.newQuery().ownedBy(player).whereBasePlot().withSortingStrategy(SortingStrategy.SORT_BY_TEMP));
break; break;
case "shared": case "shared":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) {
@ -150,13 +184,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_SHARED); Captions.PERMISSION_LIST_SHARED);
return false; return false;
} }
plots = new ArrayList<>(); plotConsumer.accept(PlotQuery.newQuery().withMember(player.getUUID()).thatPasses(plot -> !plot.isOwnerAbs(player.getUUID())));
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getTrusted().contains(player.getUUID()) || plot.getMembers()
.contains(player.getUUID())) {
plots.add(plot);
}
}
break; break;
case "world": case "world":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) {
@ -171,7 +199,7 @@ public class ListCmd extends SubCommand {
world)); world));
return false; return false;
} }
plots = new ArrayList<>(PlotSquared.get().getPlots(world)); plotConsumer.accept(PlotQuery.newQuery().inWorld(world));
break; break;
case "expired": case "expired":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) {
@ -179,9 +207,11 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_EXPIRED); Captions.PERMISSION_LIST_EXPIRED);
return false; return false;
} }
plots = ExpireManager.IMP == null ? if (ExpireManager.IMP == null) {
new ArrayList<Plot>() : plotConsumer.accept(PlotQuery.newQuery().noPlots());
new ArrayList<>(ExpireManager.IMP.getPendingExpired()); } else {
plotConsumer.accept(PlotQuery.newQuery().expiredPlots());
}
break; break;
case "area": case "area":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) {
@ -196,7 +226,11 @@ public class ListCmd extends SubCommand {
world)); world));
return false; return false;
} }
plots = area == null ? new ArrayList<Plot>() : new ArrayList<>(area.getPlots()); if (area == null) {
plotConsumer.accept(PlotQuery.newQuery().noPlots());
} else {
plotConsumer.accept(PlotQuery.newQuery().inArea(area));
}
break; break;
case "all": case "all":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) {
@ -204,7 +238,7 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL);
return false; return false;
} }
plots = new ArrayList<>(PlotSquared.get().getPlots()); plotConsumer.accept(PlotQuery.newQuery().allPlots());
break; break;
case "done": case "done":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) {
@ -212,24 +246,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE);
return false; return false;
} }
plots = new ArrayList<>(); sort[0] = false;
for (Plot plot : PlotSquared.get().getPlots()) { plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE));
if (DoneFlag.isDone(plot)) {
plots.add(plot);
}
}
plots.sort((a, b) -> {
String va = a.getFlag(DoneFlag.class);
String vb = b.getFlag(DoneFlag.class);
if (MathMan.isInteger(va)) {
if (MathMan.isInteger(vb)) {
return Integer.parseInt(vb) - Integer.parseInt(va);
}
return -1;
}
return 1;
});
sort = false;
break; break;
case "top": case "top":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) {
@ -237,32 +255,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP);
return false; return false;
} }
plots = new ArrayList<>(PlotSquared.get().getPlots()); sort[0] = false;
plots.sort((p1, p2) -> { plotConsumer.accept(PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING));
double v1 = 0;
int p1s = p1.getSettings().getRatings().size();
int p2s = p2.getRatings().size();
if (!p1.getSettings().getRatings().isEmpty()) {
v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating)
.map(av -> av * av).sum();
v1 /= p1s;
v1 += p1s;
}
double v2 = 0;
if (!p2.getSettings().getRatings().isEmpty()) {
for (Entry<UUID, Rating> entry : p2.getRatings().entrySet()) {
double av = entry.getValue().getAverageRating();
v2 += av * av;
}
v2 /= p2s;
v2 += p2s;
}
if (v2 == v1 && v2 != 0) {
return p2s - p1s;
}
return (int) Math.signum(v2 - v1);
});
sort = false;
break; break;
case "forsale": case "forsale":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
@ -270,15 +264,10 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_FOR_SALE); Captions.PERMISSION_LIST_FOR_SALE);
return false; return false;
} }
if (EconHandler.manager == null) { if (EconHandler.getEconHandler() == null) {
break; break;
} }
plots = new ArrayList<>(); plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0));
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getFlag(PriceFlag.class) > 0) {
plots.add(plot);
}
}
break; break;
case "unowned": case "unowned":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) {
@ -286,28 +275,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_UNOWNED); Captions.PERMISSION_LIST_UNOWNED);
return false; return false;
} }
plots = new ArrayList<>(); plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getOwner() == null));
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getOwner() == null) {
plots.add(plot);
}
}
break;
case "unknown":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_LIST_UNKNOWN);
return false;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getOwner() == null) {
continue;
}
if (UUIDHandler.getName(plot.getOwner()) == null) {
plots.add(plot);
}
}
break; break;
case "fuzzy": case "fuzzy":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) {
@ -325,8 +293,8 @@ public class ListCmd extends SubCommand {
} else { } else {
term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " "); term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " ");
} }
plots = MainUtil.getPlotsBySearch(term); sort[0] = false;
sort = false; plotConsumer.accept(PlotQuery.newQuery().plotsBySearch(term));
break; break;
default: default:
if (PlotSquared.get().hasPlotArea(args[0])) { if (PlotSquared.get().hasPlotArea(args[0])) {
@ -343,50 +311,43 @@ public class ListCmd extends SubCommand {
args[0])); args[0]));
return false; return false;
} }
plots = new ArrayList<>(PlotSquared.get().getPlots(args[0])); plotConsumer.accept(PlotQuery.newQuery().inWorld(args[0]));
break;
}
UUID uuid = UUIDHandler.getUUID(args[0], null);
if (uuid == null) {
try {
uuid = UUID.fromString(args[0]);
} catch (Exception ignored) {
}
}
if (uuid != null) {
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_LIST_PLAYER);
return false;
}
sort = false;
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots(uuid));
break; break;
} }
PlotSquared.get().getImpromptuUUIDPipeline()
.getSingle(args[0], (uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} else if (throwable != null) {
if (uuid == null) {
try {
uuid = UUID.fromString(args[0]);
} catch (Exception ignored) {
}
}
}
if (uuid == null) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]);
} else {
if (!Permissions
.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_LIST_PLAYER);
} else {
sort[0] = false;
plotConsumer.accept(PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP));
}
}
});
} }
if (plots == null) {
sendMessage(player, Captions.DID_YOU_MEAN,
new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"})
.getBestMatch());
return false;
}
if (plots.isEmpty()) {
MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS);
return false;
}
displayPlots(player, plots, 12, page, area, args, sort);
return true; return true;
} }
public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page, public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page, String[] args) {
PlotArea area, String[] args, boolean sort) {
// Header // Header
plots.removeIf(plot -> !plot.isBasePlot()); plots.removeIf(plot -> !plot.isBasePlot());
if (sort) {
plots = PlotSquared.get().sortPlots(plots, SortType.CREATION_DATE, area);
}
this.paginate(player, plots, pageSize, page, this.paginate(player, plots, pageSize, page,
new RunnableVal3<Integer, Plot, PlotMessage>() { new RunnableVal3<Integer, Plot, PlotMessage>() {
@Override public void run(Integer i, Plot plot, PlotMessage message) { @Override public void run(Integer i, Plot plot, PlotMessage message) {
@ -417,25 +378,72 @@ public class ListCmd extends SubCommand {
.command("/plot info " + plot.getArea() + ";" + plot.getId()).color(color) .command("/plot info " + plot.getArea() + ";" + plot.getId()).color(color)
.text(" - ").color("$2"); .text(" - ").color("$2");
String prefix = ""; String prefix = "";
for (UUID uuid : plot.getOwners()) {
String name = UUIDHandler.getName(uuid); try {
if (name == null) { final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline()
message = message.text(prefix).color("$4").text("unknown").color("$2") .getNames(plot.getOwners()).get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS);
.tooltip(uuid.toString()).suggest(uuid.toString()); for (final UUIDMapping uuidMapping : names) {
} else { PlotPlayer pp = PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuidMapping.getUuid());
PlotPlayer pp = UUIDHandler.getPlayer(uuid);
if (pp != null) { if (pp != null) {
message = message.text(prefix).color("$4").text(name).color("$1") message = message.text(prefix).color("$4").text(uuidMapping.getUsername()).color("$1")
.tooltip(new PlotMessage("Online").color("$4")); .tooltip(new PlotMessage("Online").color("$4"));
} else { } else {
message = message.text(prefix).color("$4").text(name).color("$1") message = message.text(prefix).color("$4").text(uuidMapping.getUsername()).color("$1")
.tooltip(new PlotMessage("Offline").color("$3")); .tooltip(new PlotMessage("Offline").color("$3"));
} }
prefix = ", ";
} }
prefix = ", "; } catch (InterruptedException | ExecutionException e) {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER);
} catch (TimeoutException e) {
MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} }
} }
}, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated()); }, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated());
} }
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<String> completions = new LinkedList<>();
if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
completions.add("forsale");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) {
completions.add("mine");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) {
completions.add("shared");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) {
completions.addAll(PlotSquared.imp().getWorldManager().getWorlds());
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) {
completions.add("top");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) {
completions.add("all");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) {
completions.add("unowned");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) {
completions.add("done");
}
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) {
completions.add("expired");
}
final List<Command> commands = new LinkedList<>();
commands.addAll(completions.stream()
.filter(completion -> completion.toLowerCase().startsWith(args[0].toLowerCase()))
.map(completion -> new Command(null, true, completion, "", RequiredType.NONE, CommandCategory.TELEPORT) {})
.collect(Collectors.toList()));
if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER) && args[0].length() > 0) {
commands.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList()));
}
return commands;
}
} }

View File

@ -52,7 +52,7 @@ import java.util.List;
usage = "/plot load") usage = "/plot load")
public class Load extends SubCommand { public class Load extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
String world = player.getLocation().getWorld(); String world = player.getLocation().getWorld();
if (!PlotSquared.get().hasPlotArea(world)) { if (!PlotSquared.get().hasPlotArea(world)) {
return !sendMessage(player, Captions.NOT_IN_PLOT_WORLD); return !sendMessage(player, Captions.NOT_IN_PLOT_WORLD);
@ -152,7 +152,7 @@ public class Load extends SubCommand {
return true; return true;
} }
public void displaySaves(PlotPlayer player) { public void displaySaves(PlotPlayer<?> player) {
List<String> schematics = player.getMeta("plot_schematics"); List<String> schematics = player.getMeta("plot_schematics");
for (int i = 0; i < Math.min(schematics.size(), 32); i++) { for (int i = 0; i < Math.min(schematics.size(), 32); i++) {
try { try {

View File

@ -99,7 +99,6 @@ public class MainCommand extends Command {
new DebugPaste(); new DebugPaste();
new Unlink(); new Unlink();
new Kick(); new Kick();
new DebugClaimTest();
new Inbox(); new Inbox();
new Comment(); new Comment();
new DatabaseCommand(); new DatabaseCommand();
@ -165,14 +164,14 @@ public class MainCommand extends Command {
public void run(final Command cmd, final Runnable success, final Runnable failure) { public void run(final Command cmd, final Runnable success, final Runnable failure) {
if (cmd.hasConfirmation(player)) { if (cmd.hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd.getUsage(), () -> { CmdConfirm.addPending(player, cmd.getUsage(), () -> {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = Expression<Double> priceEval =
area.getPrices().get(cmd.getFullId()); area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != null if (price != null
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }
@ -186,12 +185,12 @@ public class MainCommand extends Command {
}); });
return; return;
} }
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = area.getPrices().get(cmd.getFullId()); Expression<Double> priceEval = area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d && EconHandler.manager.getMoney(player) < price) { if (price != 0d && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }
@ -218,7 +217,7 @@ public class MainCommand extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
// Clear perm caching // // Clear perm caching //
@ -253,14 +252,14 @@ public class MainCommand extends Command {
if ("f".equals(args[0].substring(1))) { if ("f".equals(args[0].substring(1))) {
confirm = new RunnableVal3<Command, Runnable, Runnable>() { confirm = new RunnableVal3<Command, Runnable, Runnable>() {
@Override public void run(Command cmd, Runnable success, Runnable failure) { @Override public void run(Command cmd, Runnable success, Runnable failure) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = Expression<Double> priceEval =
area.getPrices().get(cmd.getFullId()); area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d if (price != 0d
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }

View File

@ -40,7 +40,6 @@ import com.plotsquared.core.util.Expression;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.UUID; import java.util.UUID;
@ -79,7 +78,7 @@ public class Merge extends SubCommand {
} }
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocationFull(); Location location = player.getLocationFull();
final Plot plot = location.getPlotAbs(); final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
@ -157,8 +156,8 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.autoMerge(Direction.ALL, maxSize, uuid, terrain)) { if (plot.autoMerge(Direction.ALL, maxSize, uuid, terrain)) {
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@ -172,11 +171,11 @@ public class Merge extends SubCommand {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false; return false;
} else { } else {
uuid = plot.guessOwner(); uuid = plot.getOwnerAbs();
} }
} }
if (!force && EconHandler.manager != null && plotArea.useEconomy() && price > 0d if (!force && EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price)); sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return false; return false;
} }
@ -193,8 +192,8 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) { if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) {
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@ -213,7 +212,7 @@ public class Merge extends SubCommand {
java.util.Set<UUID> uuids = adjacent.getOwners(); java.util.Set<UUID> uuids = adjacent.getOwners();
boolean isOnline = false; boolean isOnline = false;
for (final UUID owner : uuids) { for (final UUID owner : uuids) {
final PlotPlayer accepter = UUIDHandler.getPlayer(owner); final PlotPlayer accepter = PlotSquared.imp().getPlayerManager().getPlayerIfExists(owner);
if (!force && accepter == null) { if (!force && accepter == null) {
continue; continue;
} }
@ -222,17 +221,17 @@ public class Merge extends SubCommand {
Runnable run = () -> { Runnable run = () -> {
MainUtil.sendMessage(accepter, Captions.MERGE_ACCEPTED); MainUtil.sendMessage(accepter, Captions.MERGE_ACCEPTED);
plot.autoMerge(dir, maxSize - size, owner, terrain); plot.autoMerge(dir, maxSize - size, owner, terrain);
PlotPlayer plotPlayer = UUIDHandler.getPlayer(player.getUUID()); PlotPlayer plotPlayer = PlotSquared.imp().getPlayerManager().getPlayerIfExists(player.getUUID());
if (plotPlayer == null) { if (plotPlayer == null) {
sendMessage(accepter, Captions.MERGE_NOT_VALID); sendMessage(accepter, Captions.MERGE_NOT_VALID);
return; return;
} }
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
if (!force && EconHandler.manager.getMoney(player) < price) { if (!force && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price)); sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return; return;
} }
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);

View File

@ -42,7 +42,7 @@ import com.plotsquared.core.plot.Plot;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Middle extends SubCommand { public class Middle extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] arguments) { @Override public boolean onCommand(PlotPlayer<?> player, String[] arguments) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot = location.getPlot(); Plot plot = location.getPlot();
if (plot == null) { if (plot == null) {

View File

@ -47,7 +47,7 @@ import java.util.concurrent.CompletableFuture;
public class Move extends SubCommand { public class Move extends SubCommand {
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
Location location = player.getLocation(); Location location = player.getLocation();
@ -107,7 +107,7 @@ public class Move extends SubCommand {
}); });
} }
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
return true; return true;
} }

View File

@ -55,7 +55,7 @@ public class Music extends SubCommand {
"music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal", "music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal",
"music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait"); "music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait");
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Location location = player.getLocation();
final Plot plot = location.getPlotAbs(); final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {

View File

@ -46,7 +46,7 @@ public class Near extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT); final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT);

View File

@ -36,10 +36,11 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
@CommandDeclaration(command = "setowner", @CommandDeclaration(command = "setowner",
permission = "plots.set.owner", permission = "plots.set.owner",
@ -57,91 +58,103 @@ public class Owner extends SetCommand {
return false; return false;
} }
Set<Plot> plots = plot.getConnectedPlots(); Set<Plot> plots = plot.getConnectedPlots();
UUID uuid = null;
final Consumer<UUID> uuidConsumer = uuid -> {
if (uuid == null && !value.equalsIgnoreCase("none") && !value.equalsIgnoreCase("null")
&& !value.equalsIgnoreCase("-")) {
Captions.INVALID_PLAYER.send(player, value);
return;
}
PlotChangeOwnerEvent event = PlotSquared.get().getEventDispatcher()
.callOwnerChange(player, plot, plot.hasOwner() ? plot.getOwnerAbs() : null, uuid,
plot.hasOwner());
if (event.getEventResult() == Result.DENY) {
sendMessage(player, Captions.EVENT_DENIED, "Owner change");
return;
}
uuid = event.getNewOwner();
boolean force = event.getEventResult() == Result.FORCE;
if (uuid == null) {
if (!force && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SET_OWNER.getTranslated(),
true)) {
return;
}
PlotUnlinkEvent unlinkEvent = PlotSquared.get().getEventDispatcher()
.callUnlink(plot.getArea(), plot, false, false, PlotUnlinkEvent.REASON.NEW_OWNER);
if (unlinkEvent.getEventResult() == Result.DENY) {
sendMessage(player, Captions.EVENT_DENIED, "Unlink on owner change");
return;
}
plot.unlinkPlot(unlinkEvent.isCreateRoad(), unlinkEvent.isCreateRoad());
Set<Plot> connected = plot.getConnectedPlots();
for (Plot current : connected) {
current.unclaim();
current.removeSign();
}
MainUtil.sendMessage(player, Captions.SET_OWNER);
return;
}
final PlotPlayer other = PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuid);
if (plot.isOwner(uuid)) {
Captions.ALREADY_OWNER.send(player, MainUtil.getName(uuid));
return;
}
if (!force && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SET_OWNER)) {
if (other == null) {
Captions.INVALID_PLAYER_OFFLINE.send(player, value);
return;
}
int size = plots.size();
int currentPlots = (Settings.Limit.GLOBAL ?
other.getPlotCount() :
other.getPlotCount(plot.getWorldName())) + size;
if (currentPlots > other.getAllowedPlots()) {
sendMessage(player, Captions.CANT_TRANSFER_MORE_PLOTS);
return;
}
}
final UUID finalUUID = uuid;
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(uuid, (finalName, throwable) -> {
final boolean removeDenied = plot.isDenied(finalUUID);
Runnable run = () -> {
if (plot.setOwner(finalUUID, player)) {
if (removeDenied)
plot.removeDenied(finalUUID);
plot.setSign(finalName);
MainUtil.sendMessage(player, Captions.SET_OWNER);
if (other != null) {
MainUtil.sendMessage(other, Captions.NOW_OWNER,
plot.getArea() + ";" + plot.getId());
}
} else {
MainUtil.sendMessage(player, Captions.SET_OWNER_CANCELLED);
}
};
if (hasConfirmation(player)) {
CmdConfirm.addPending(player, "/plot set owner " + value, run);
} else {
TaskManager.runTask(run);
}
});
};
if (value.length() == 36) { if (value.length() == 36) {
try { try {
uuid = UUID.fromString(value); uuidConsumer.accept(UUID.fromString(value));
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} else { } else {
uuid = UUIDHandler.getUUID(value, null); PlotSquared.get().getImpromptuUUIDPipeline().getSingle(value, (uuid, throwable) -> {
} if (throwable instanceof TimeoutException) {
if (uuid == null && !value.equalsIgnoreCase("none") && !value.equalsIgnoreCase("null") MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
&& !value.equalsIgnoreCase("-")) { } else if (throwable != null) {
Captions.INVALID_PLAYER.send(player, value); MainUtil.sendMessage(player, Captions.INVALID_PLAYER, value);
return false; } else {
} uuidConsumer.accept(uuid);
PlotChangeOwnerEvent event = PlotSquared.get().getEventDispatcher() }
.callOwnerChange(player, plot, plot.hasOwner() ? plot.getOwnerAbs() : null, uuid, });
plot.hasOwner());
if (event.getEventResult() == Result.DENY) {
sendMessage(player, Captions.EVENT_DENIED, "Owner change");
return false;
}
uuid = event.getNewOwner();
boolean force = event.getEventResult() == Result.FORCE;
if (uuid == null) {
if (!force && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SET_OWNER.getTranslated(),
true)) {
return false;
}
PlotUnlinkEvent unlinkEvent = PlotSquared.get().getEventDispatcher()
.callUnlink(plot.getArea(), plot, false, false, PlotUnlinkEvent.REASON.NEW_OWNER);
if (unlinkEvent.getEventResult() == Result.DENY) {
sendMessage(player, Captions.EVENT_DENIED, "Unlink on owner change");
return true;
}
plot.unlinkPlot(unlinkEvent.isCreateRoad(), unlinkEvent.isCreateRoad());
Set<Plot> connected = plot.getConnectedPlots();
for (Plot current : connected) {
current.unclaim();
current.removeSign();
}
MainUtil.sendMessage(player, Captions.SET_OWNER);
return true;
}
final PlotPlayer other = UUIDHandler.getPlayer(uuid);
if (plot.isOwner(uuid)) {
Captions.ALREADY_OWNER.send(player, MainUtil.getName(uuid));
return false;
}
if (!force && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SET_OWNER)) {
if (other == null) {
Captions.INVALID_PLAYER_OFFLINE.send(player, value);
return false;
}
int size = plots.size();
int currentPlots = (Settings.Limit.GLOBAL ?
other.getPlotCount() :
other.getPlotCount(plot.getWorldName())) + size;
if (currentPlots > other.getAllowedPlots()) {
sendMessage(player, Captions.CANT_TRANSFER_MORE_PLOTS);
return false;
}
}
final String finalName = UUIDHandler.getName(uuid);
final UUID finalUUID = uuid;
final boolean removeDenied = plot.isDenied(finalUUID);
Runnable run = () -> {
if (plot.setOwner(finalUUID, player)) {
if (removeDenied)
plot.removeDenied(finalUUID);
plot.setSign(finalName);
MainUtil.sendMessage(player, Captions.SET_OWNER);
if (other != null) {
MainUtil.sendMessage(other, Captions.NOW_OWNER,
plot.getArea() + ";" + plot.getId());
}
} else {
MainUtil.sendMessage(player, Captions.SET_OWNER_CANCELLED);
}
};
if (hasConfirmation(player)) {
CmdConfirm.addPending(player, "/plot set owner " + value, run);
} else {
TaskManager.runTask(run);
} }
return true; return true;
} }

View File

@ -39,7 +39,7 @@ import com.plotsquared.core.util.task.TaskManager;
category = CommandCategory.INFO) category = CommandCategory.INFO)
public class PluginCmd extends SubCommand { public class PluginCmd extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
TaskManager.IMP.taskAsync(() -> { TaskManager.IMP.taskAsync(() -> {
MainUtil.sendMessage(player, String.format( MainUtil.sendMessage(player, String.format(
"$2>> $1&l" + PlotSquared.imp().getPluginName() + " $2($1Version$2: $1%s$2)", "$2>> $1&l" + PlotSquared.imp().getPluginName() + " $2($1Version$2: $1%s$2)",

View File

@ -36,7 +36,6 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -54,7 +53,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
confirmation = true) confirmation = true)
public class Purge extends SubCommand { public class Purge extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
if (args.length == 0) { if (args.length == 0) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return false; return false;
@ -65,7 +64,6 @@ public class Purge extends SubCommand {
PlotId id = null; PlotId id = null;
UUID owner = null; UUID owner = null;
UUID added = null; UUID added = null;
boolean unknown = false;
boolean clear = false; boolean clear = false;
for (String arg : args) { for (String arg : args) {
String[] split = arg.split(":"); String[] split = arg.split(":");
@ -97,7 +95,7 @@ public class Purge extends SubCommand {
break; break;
case "owner": case "owner":
case "o": case "o":
owner = UUIDHandler.getUUID(split[1], null); owner = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(split[1], Settings.UUID.BLOCKING_TIMEOUT);
if (owner == null) { if (owner == null) {
Captions.INVALID_PLAYER.send(player, split[1]); Captions.INVALID_PLAYER.send(player, split[1]);
return false; return false;
@ -105,17 +103,12 @@ public class Purge extends SubCommand {
break; break;
case "shared": case "shared":
case "s": case "s":
added = UUIDHandler.getUUID(split[1], null); added = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(split[1], Settings.UUID.BLOCKING_TIMEOUT);
if (added == null) { if (added == null) {
Captions.INVALID_PLAYER.send(player, split[1]); Captions.INVALID_PLAYER.send(player, split[1]);
return false; return false;
} }
break; break;
case "unknown":
case "?":
case "u":
unknown = Boolean.parseBoolean(split[1]);
break;
case "clear": case "clear":
case "c": case "c":
case "delete": case "delete":
@ -145,9 +138,6 @@ public class Purge extends SubCommand {
if (added != null && !plot.isAdded(added)) { if (added != null && !plot.isAdded(added)) {
continue; continue;
} }
if (unknown && UUIDHandler.getName(plot.getOwnerAbs()) != null) {
continue;
}
toDelete.addAll(plot.getConnectedPlots()); toDelete.addAll(plot.getConnectedPlots());
} }
if (PlotSquared.get().plots_tmp != null) { if (PlotSquared.get().plots_tmp != null) {
@ -168,9 +158,6 @@ public class Purge extends SubCommand {
if (added != null && !plot.isAdded(added)) { if (added != null && !plot.isAdded(added)) {
continue; continue;
} }
if (unknown && UUIDHandler.getName(plot.getOwnerAbs()) != null) {
continue;
}
toDelete.add(plot); toDelete.add(plot);
} }
} }

View File

@ -56,7 +56,7 @@ import java.util.UUID;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Rate extends SubCommand { public class Rate extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
if (args.length == 1) { if (args.length == 1) {
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "next": { case "next": {

View File

@ -43,7 +43,7 @@ import com.plotsquared.core.util.MainUtil;
permission = "plots.regenallroads") permission = "plots.regenallroads")
public class RegenAllRoads extends SubCommand { public class RegenAllRoads extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
int height = 0; int height = 0;
if (args.length == 2) { if (args.length == 2) {
try { try {

View File

@ -47,7 +47,7 @@ public class Relight extends Command {
} }
@Override @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();

View File

@ -45,7 +45,7 @@ import java.util.Objects;
category = CommandCategory.ADMINISTRATION) category = CommandCategory.ADMINISTRATION)
public class Reload extends SubCommand { public class Reload extends SubCommand {
@Override public boolean onCommand(PlotPlayer player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
try { try {
// The following won't affect world generation, as that has to be // The following won't affect world generation, as that has to be
// loaded during startup unfortunately. // loaded during startup unfortunately.

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