Compare commits
No commits in common. "1.7.4" and "master" have entirely different histories.
|
@ -0,0 +1,3 @@
|
|||
github: [Phoenix616]
|
||||
patreon: Phoenix616
|
||||
custom: https://phoenix616.dev/tip
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Report an error that that you found
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Plugin Version
|
||||
<!-- The full plugin version like it is printed in the log or /version RandomTeleport -->
|
||||
|
||||
|
||||
#### Config
|
||||
<!-- The full config file -->
|
||||
```yaml
|
||||
[Put the config here]
|
||||
```
|
||||
|
||||
#### Environment description
|
||||
<!-- Information like the operating system and language as well as full server version from /version -->
|
||||
|
||||
|
||||
#### Full Log
|
||||
<!-- The full log file, especially important if you have a stack trace -->
|
||||
```
|
||||
[Your log here]
|
||||
```
|
||||
|
||||
#### What other programs/plugins are you running?
|
||||
<!-- List of your plugins, ideally with the version or other programs that might be related -->
|
||||
|
||||
|
||||
#### What is happening?
|
||||
<!-- Explain what happens and what steps should be done to reproduce the issue. Ideally with pictures and the full error log! -->
|
||||
|
||||
|
||||
#### What did you expect to happen?
|
||||
<!-- Explain what you expected to happen after performing the previously described steps -->
|
||||
|
||||
|
||||
#### Additional context
|
||||
<!-- Add any other context or screenshots about the bug report here. -->
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "#moep IRC channel on irc.spi.gt"
|
||||
url: "https://kiwiirc.com/client/irc.spi.gt/#moep"
|
||||
about: My public chat channel to discuss any of my projects
|
||||
- name: SpigotMC Discussion Thread
|
||||
url: https://www.spigotmc.org/threads/fubs-random-teleport.29162/
|
||||
about: Ask questions and discuss the resource publicly
|
||||
- name: SpigotMC PM
|
||||
url: https://www.spigotmc.org/conversations/add?to=Phoenix616&title=RandomTeleport%20Question
|
||||
about: Ask me questions privately
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: Enhancement
|
||||
about: Request a feature or suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Is your feature request related to a problem? Please describe.
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when... -->
|
||||
|
||||
|
||||
#### Describe the solution you'd like
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
|
||||
#### Describe alternatives you've considered
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
|
||||
#### Additional context
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
|
|
@ -1,12 +1,6 @@
|
|||
bin
|
||||
*.class
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Eclipse stuff
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
# IntelliJ project files
|
||||
.idea
|
||||
*.iml
|
||||
out
|
||||
gen
|
||||
target
|
||||
|
|
84
README.md
84
README.md
|
@ -1,6 +1,86 @@
|
|||
RandomTeleport
|
||||
RandomTeleport v2
|
||||
==============
|
||||
|
||||
Plugin which lets you teleport players to a random location of a map within your provided paramaters.
|
||||
Second generation random teleport Bukkit Plugin.
|
||||
|
||||
Lets you teleport players to a random location of a map within your provided parameters while respecting stuff like world borders and region protections.
|
||||
|
||||
SpigotMC resource page: http://www.spigotmc.org/resources/fubs-random-teleport.1094/
|
||||
|
||||
## Command
|
||||
|
||||
Aliases: `randomteleport`, `randomtp`, `rtp`
|
||||
|
||||
Permission: `randomteleport.use`
|
||||
|
||||
Usage | Description
|
||||
--------------------------------------------|-------------------------------
|
||||
`/rtp` | uses the default preset
|
||||
`/rtp <preset1,...> [<playername>]` | uses a specific or random preset
|
||||
`/rtp <minRange> <maxRange> [<options>]` | `minRange` - minimum distance to the center point (square shaped) <br> `maxRange` - maximum distance to the center point (square shaped)
|
||||
`/rtp --stat` | shows a statistic of the teleports since the last restart
|
||||
`/rtp --reload` | reloads the config
|
||||
|
||||
Option | Description
|
||||
--------------------------------|-------------------------------------------
|
||||
`-p,-player <playername>` | teleports other players
|
||||
`-w,-world <world1,world2,...>` | teleports the player in a specific or random world
|
||||
`-b,-biome <biomename...>` | only teleport to this biome (multiple allowed, Bukkit biome names!)
|
||||
`-x,-xPos <x value>` | x axis of the center point, if not set the player's x axis is used
|
||||
`-z,-zPos <z value>` | z axis of the center point, if not set the player's z axis is used
|
||||
`-minY <y value>` | minimum y value that the random location should have (default: 0)
|
||||
`-maxY <y value>` | maximum y value that the random location should have (default: world height, half in nether)
|
||||
`-l,-loaded` | only search loaded chunks for possible locations (might fail more often)
|
||||
`-g,-generated` | only search generated chunks for possible locations
|
||||
`-c, -cooldown <seconds>` | cooldown in seconds after which the player can use this teleporter again
|
||||
`-id <id>` | the ID to use for the cooldown, uses automatically generated one if not provided
|
||||
`-f,-force` | teleport even if there is no dirt/grass/sand/gravel, only checks for lava/water/cactus, ignores WorldGuard/Faction regions
|
||||
`-f,-force [<blocks/regions>]` | only ignore blocks or regions
|
||||
`-t,-tries <amount>` | the amount of times the plugin should try to find a random location before giving up
|
||||
`-sp,spawnpoint [force]` | set the respawn point of the player to the location he teleported to (force overrides existing spawnpoint)
|
||||
`-checkdelay <ticks>` | the amount of ticks to wait between each chunk check
|
||||
`-debug` | print some more debugging information in the log
|
||||
|
||||
## Permissions
|
||||
|
||||
Permission | Default | Description
|
||||
------------------------------------|---------|---------------------------
|
||||
randomteleport.use | op | Gives permission to the command
|
||||
randomteleport.manual | op | Gives permission to manually specify parameters in the command
|
||||
randomteleport.manual.option.* | op | Gives permission to use certain options in the command
|
||||
randomteleport.tpothers | op | Gives permission to teleport other players
|
||||
randomteleport.cooldownexempt | op | Teleportcooldown does not effect these players
|
||||
randomteleport.stat | op | Permission for showing the teleport statistic
|
||||
randomteleport.reload | op | Permission to use the reload command
|
||||
randomteleport.presets.default | op | Gives permission to use the default random teleport preset
|
||||
randomteleport.presets.* | op | Gives permission to use all random teleport presets
|
||||
randomteleport.sign.preset.default | op | Gives permission to use the default preset with a rightclick on a preset sign
|
||||
randomteleport.sign.preset.* | op | Gives permission to use all presets with a rightclick on a preset sign
|
||||
randomteleport.sign.create | op | Allows creating preset signs ([rtp] or [RandomTP] on the 2nd line and the preset name on the 3rd)
|
||||
randomteleport.sign.destroy | op | Allows destroying preset signs ([rtp] or [RandomTP] on the 2nd line and the preset name on the 3rd)
|
||||
|
||||
## Downloads
|
||||
|
||||
Releases: [SpigotMC resource page](http://www.spigotmc.org/resources/fubs-random-teleport.1094/)
|
||||
|
||||
Development Builds: [Minebench.de Jenkins server](https://ci.minebench.de/job/Randomteleport/)
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
RandomTeleport
|
||||
Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
|
||||
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/>.
|
||||
```
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,130 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.themoep</groupId>
|
||||
<artifactId>RandomTeleport</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<description>Randomly teleport players on your server!</description>
|
||||
<name>RandomTeleport</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<build.number>${buildNumber}</build.number>
|
||||
<minecraft.plugin.version>${project.version} ${buildDescription}</minecraft.plugin.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sk89q-repo</id>
|
||||
<url>http://maven.sk89q.com/repo/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minebench-repo</id>
|
||||
<url>http://repo.minebench.de/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.9-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.themoep</groupId>
|
||||
<artifactId>ClanControl</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldguard</artifactId>
|
||||
<version>6.1.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.ryanhamshire</groupId>
|
||||
<artifactId>GriefPrevention</artifactId>
|
||||
<version>13.6</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/GriefPrevention-13.6.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft</groupId>
|
||||
<artifactId>MassiveCore</artifactId>
|
||||
<version>2.7.1</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/MassiveCore-2.7.1.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft</groupId>
|
||||
<artifactId>MassiveCore-old</artifactId>
|
||||
<version>7.4.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/MassiveCore-7.4.0.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.themoep</groupId>
|
||||
<artifactId>factionsutil</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/Factions-Dependencies-2.6+2.7.1+UUID.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.Brettflan</groupId>
|
||||
<artifactId>WorldBorder</artifactId>
|
||||
<version>master-c5df3417c8-1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>static_build_number</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildNumber>0</buildNumber>
|
||||
<buildDescription>(manually compiled)</buildDescription>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dynamic_build_number</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildNumber>${env.BUILD_NUMBER}</buildNumber>
|
||||
<buildDescription>(build #${env.BUILD_NUMBER})</buildDescription>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<finalName>${project.name}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,75 +0,0 @@
|
|||
package de.themoep.bukkit.plugin.RandomTeleport.Listeners;
|
||||
|
||||
import de.themoep.bukkit.plugin.RandomTeleport.RandomTeleport;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
/**
|
||||
* Created by Phoenix616 on 23.11.2014.
|
||||
*/
|
||||
public class SignListener implements Listener {
|
||||
|
||||
private final RandomTeleport plugin;
|
||||
|
||||
public SignListener(RandomTeleport plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSignCreate(SignChangeEvent event) {
|
||||
if(event.getLine(1).equalsIgnoreCase("[rtp]") || event.getLine(1).equalsIgnoreCase("[RandomTP]")){
|
||||
if(!event.getPlayer().hasPermission("randomteleport.sign.create")){
|
||||
event.getBlock().breakNaturally();
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to create RandomTeleport preset signs! " + ChatColor.ITALIC + " (randomteleport.sign.create)");
|
||||
} else {
|
||||
event.getPlayer().sendMessage(ChatColor.GREEN + "RandomTeleport preset sign created!");
|
||||
if(plugin.getConfig().getString("presets." + event.getLine(2).toLowerCase()) == null) {
|
||||
event.getPlayer().sendMessage(ChatColor.DARK_RED + "Warning: " + ChatColor.RED + "The RandomTeleport preset " + ChatColor.GOLD + event.getLine(2).toLowerCase() + ChatColor.RED + " does not exist!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSignDestroy(BlockBreakEvent event){
|
||||
if(event.getBlock().getType() == Material.WALL_SIGN || event.getBlock().getType() == Material.SIGN_POST) {
|
||||
Sign sign = (Sign) event.getBlock().getState();
|
||||
if(sign.getLine(1).equalsIgnoreCase("[rtp]") || sign.getLine(1).equalsIgnoreCase("[RandomTP]")){
|
||||
if(!event.getPlayer().hasPermission("randomteleport.sign.create")){
|
||||
event.setCancelled(true);
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to break RandomTeleport signs! " + ChatColor.ITALIC + " (randomteleport.sign.create)");
|
||||
} else {
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "RandomTeleport sign destroyed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSignClick(PlayerInteractEvent event) {
|
||||
if(event.getAction() == Action.RIGHT_CLICK_BLOCK && !event.isCancelled() && (event.getClickedBlock().getType() == Material.WALL_SIGN || event.getClickedBlock().getType() == Material.SIGN_POST)) {
|
||||
Sign sign = (Sign) event.getClickedBlock().getState();
|
||||
if(sign.getLine(1).equalsIgnoreCase("[rtp]") || sign.getLine(1).equalsIgnoreCase("[RandomTP]")) {
|
||||
String preset = sign.getLine(2).toLowerCase();
|
||||
if(event.getPlayer().hasPermission("randomteleport.sign.preset." + preset)) {
|
||||
if(plugin.getConfig().getString("presets." + preset) == null) {
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "The RandomTeleport preset " + ChatColor.GOLD + preset + ChatColor.RED + " does not exist!");
|
||||
} else {
|
||||
String cmd = "rtp " + preset + " " + event.getPlayer().getName();
|
||||
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), cmd);
|
||||
}
|
||||
} else {
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to use the preset " + preset + "! " + ChatColor.ITALIC + " (randomteleport.sign.preset." + preset + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,824 +0,0 @@
|
|||
package de.themoep.bukkit.plugin.RandomTeleport;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.wimbli.WorldBorder.BorderData;
|
||||
import com.wimbli.WorldBorder.WorldBorder;
|
||||
import de.themoep.bukkit.plugin.RandomTeleport.Listeners.SignListener;
|
||||
import de.themoep.clancontrol.ClanControl;
|
||||
import de.themoep.clancontrol.Region;
|
||||
import de.themoep.clancontrol.RegionStatus;
|
||||
import me.ryanhamshire.GriefPrevention.GriefPrevention;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockCanBuildEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public class RandomTeleport extends JavaPlugin implements CommandExecutor {
|
||||
|
||||
public static RandomTeleport instance;
|
||||
|
||||
public Level debugLevel;
|
||||
|
||||
public HashMap<String,Long> cooldown = new HashMap<String,Long> ();
|
||||
public HashSet<UUID> playerlock = new HashSet<UUID> ();
|
||||
public int[] checkstat = new int[100];
|
||||
|
||||
public int factionsApiVersion = 0;
|
||||
public boolean worldguard = false;
|
||||
public boolean clancontrol = false;
|
||||
public boolean griefprevention = false;
|
||||
public boolean worldborder = false;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
loadConfig();
|
||||
|
||||
getLogger().log(Level.INFO, "Attempting to load cooldown.map...");
|
||||
cooldown = (HashMap<String, Long>) readMap("cooldown.map");
|
||||
|
||||
getServer().getPluginManager().registerEvents(new SignListener(this), this);
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("WorldGuard") != null){
|
||||
getLogger().log(Level.INFO, "Detected WorldGuard.");
|
||||
worldguard = true;
|
||||
}
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("GriefPrevention") != null) {
|
||||
getLogger().log(Level.INFO, "Detected GriefPrevention.");
|
||||
griefprevention = true;
|
||||
}
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("ClanControl") != null){
|
||||
getLogger().log(Level.INFO, "Detected ClanControl.");
|
||||
clancontrol = true;
|
||||
}
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("WorldBorder") != null) {
|
||||
getLogger().log(Level.INFO, "Detected WorldBorder.");
|
||||
worldborder = true;
|
||||
}
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("Factions") != null){
|
||||
String version = Bukkit.getPluginManager().getPlugin("Factions").getDescription().getVersion();
|
||||
if(version.startsWith("2.7") || version.startsWith("2.8") || version.startsWith("2.9") || version.startsWith("2.10")) {
|
||||
factionsApiVersion = 27;
|
||||
} else if(version.startsWith("1.6")){
|
||||
factionsApiVersion = 16;
|
||||
} else {
|
||||
factionsApiVersion = 26;
|
||||
}
|
||||
getLogger().log(Level.INFO, "Detected Factions " + version + ".");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
saveDefaultConfig();
|
||||
reloadConfig();
|
||||
|
||||
debugLevel = getConfig().getBoolean("debug", false) ? Level.INFO : Level.FINER;
|
||||
}
|
||||
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) throws NumberFormatException {
|
||||
if(cmd.getName().equalsIgnoreCase("randomteleport") || cmd.getName().equalsIgnoreCase("randomtp") || cmd.getName().equalsIgnoreCase("rtp")) {
|
||||
boolean forceBlocks = false;
|
||||
boolean forceRegions = false;
|
||||
boolean loadedChunksOnly = false;
|
||||
/*
|
||||
0 -> don't set it
|
||||
1 -> set it only if the player doesn't have a bed spawn
|
||||
2 -> force it even if the player has a bed spawn
|
||||
*/
|
||||
int setSpawnpoint = 0;
|
||||
|
||||
//boolean tppoints = false;
|
||||
boolean xoption = false;
|
||||
boolean zoption = false;
|
||||
boolean coption = false;
|
||||
String playername = sender.getName();
|
||||
Player player = Bukkit.getServer().getPlayer(playername);
|
||||
int xCenter = 0;
|
||||
int zCenter = 0;
|
||||
int minRange;
|
||||
int maxRange;
|
||||
int cooldowntime = 0;
|
||||
World world = null;
|
||||
List<Biome> biomeList = new ArrayList<Biome>();
|
||||
|
||||
if(args.length == 0 && sender.hasPermission("randomteleport.presets.default")) {
|
||||
if(getConfig().getString("presets.default") != null) {
|
||||
String defaultcmd = getConfig().getString("presets.default").replace("/", "");
|
||||
defaultcmd = defaultcmd + " -p " + sender.getName();
|
||||
getServer().dispatchCommand(getServer().getConsoleSender(),defaultcmd);
|
||||
getLogger().log(debugLevel, "Running preset command default: " + defaultcmd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(args.length == 1 && args[0].equalsIgnoreCase("stat") && sender.hasPermission("randomteleport.stat")) {
|
||||
sender.sendMessage("--RandomTeleport statistics--");
|
||||
sender.sendMessage("Checks - Times occured");
|
||||
for(int i = 0; i < 100; i++) {
|
||||
if(checkstat[i] != 0) {
|
||||
if(i == 99) {
|
||||
sender.sendMessage(ChatColor.RED + "Canceled - " + checkstat[i] + "x");
|
||||
} else {
|
||||
sender.sendMessage(i + 1 + " - " + checkstat[i] + "x");
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length == 1 && args[0].equalsIgnoreCase("reload") && sender.hasPermission("randomteleport.reload")) {
|
||||
loadConfig();
|
||||
sender.sendMessage(ChatColor.GREEN + "Config reloaded!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length == 1 && sender.hasPermission("randomteleport.presets." + args[0].toLowerCase())) {
|
||||
if(getConfig().getString("presets." + args[0].toLowerCase()) == null) {
|
||||
sender.sendMessage(ChatColor.RED + "The Random Teleport " + args[0].toLowerCase() + " does not exist!");
|
||||
return true;
|
||||
}
|
||||
|
||||
String presetCmd = getConfig().getString("presets." + args[0].toLowerCase()).replace("/", "");
|
||||
presetCmd = presetCmd + " -p " + sender.getName();
|
||||
getLogger().log(debugLevel, "Running preset command " + args[0].toLowerCase() + ": " + presetCmd);
|
||||
getServer().dispatchCommand(getServer().getConsoleSender(), presetCmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length == 2 && sender.hasPermission("randomteleport.tpothers") && this.getConfig().getString("presets." + args[0].toLowerCase()) != null) {
|
||||
Player toTp = Bukkit.getServer().getPlayer(args[1]);
|
||||
if(toTp == null) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Player '" + args[1] + "' was not found online!");
|
||||
return true;
|
||||
}
|
||||
String defaultcmd = this.getConfig().getString("presets." + args[0].toLowerCase()).replace("/", "");
|
||||
defaultcmd = defaultcmd + " -p " + toTp.getName();
|
||||
getServer().dispatchCommand(sender,defaultcmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
// analyze the args & get parameter
|
||||
|
||||
if(!sender.hasPermission("randomteleport.use") && sender instanceof Player) {
|
||||
sender.sendMessage("You don't have the permission randomteleport.use");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length < 2) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Syntax error:" + ChatColor.RED + " Not enough arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
//set ranges
|
||||
minRange = Integer.parseInt(args[0]);
|
||||
maxRange = Integer.parseInt(args[1]);
|
||||
|
||||
if(minRange >= maxRange) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " maxRange must be bigger then minRange!");
|
||||
return true;
|
||||
}
|
||||
} catch(NumberFormatException e) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Your input contains an invalid number!");
|
||||
return true;
|
||||
}
|
||||
|
||||
//getLogger().info("Success: Parsing bounds");
|
||||
|
||||
|
||||
if(args.length > 2) {
|
||||
for(int i = 2; i < args.length; i++) {
|
||||
if(args[i].startsWith("-")) {
|
||||
if(args[i].equalsIgnoreCase("-p") || args[i].equalsIgnoreCase("-player") && sender.hasPermission("randomteleport.tpothers")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
playername = args[i+1];
|
||||
player = Bukkit.getServer().getPlayer(playername);
|
||||
i++;
|
||||
getLogger().log(debugLevel, "Player: " + playername);
|
||||
if(player == null) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Player '" + playername + "' was not found online!");
|
||||
return true;
|
||||
}
|
||||
} else if(args[i].equalsIgnoreCase("-w") || args[i].equalsIgnoreCase("-world")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
|
||||
getLogger().log(debugLevel, "World: " + args[i+1]);
|
||||
world = Bukkit.getServer().getWorld(args[i+1]);
|
||||
if(world == null) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The world \"" + args[i+1] + "\" given in the " + args[i] + " option does not exist!");
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
} else if(args[i].equalsIgnoreCase("-b") || args[i].equalsIgnoreCase("-biome")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
getLogger().log(debugLevel, "Biomes:");
|
||||
for(i = i+1; i < args.length; i++) {
|
||||
if(args[i].startsWith("-")) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
getLogger().log(debugLevel, args[i]);
|
||||
try {
|
||||
biomeList.add(Biome.valueOf(args[i].toUpperCase()));
|
||||
} catch(IllegalArgumentException e) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The biome \"" + args[i] + "\" given in the -biome option does not exist!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(biomeList.size() == 0) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Please specify at least one biome after the -biome option!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// if -x/-z option is selected set x/z it to its values
|
||||
} else if(args[i].equalsIgnoreCase("-x") || args[i].equalsIgnoreCase("-xPos")) {
|
||||
if(i+1 >= args.length || (args[i+1].startsWith("-") && !isNumeric(args[i+1].substring(1)))) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
xCenter = Integer.parseInt(args[i+1]);
|
||||
xoption = true;
|
||||
i++;
|
||||
} catch(NumberFormatException e) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Your input contains a invalid number in the " + args[i] + " option!");
|
||||
return true;
|
||||
}
|
||||
getLogger().log(debugLevel, "xCenter: " + xCenter);
|
||||
} else if(args[i].equalsIgnoreCase("-z") || args[i].equalsIgnoreCase("-zPos")) {
|
||||
if(i+1 >= args.length || (args[i+1].startsWith("-") && !isNumeric(args[i+1].substring(1)))) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
zCenter = Integer.parseInt(args[i+1]);
|
||||
zoption = true;
|
||||
i++;
|
||||
} catch(NumberFormatException e) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Your input contains a invalid number in the " + args[i] + " option!");
|
||||
return true;
|
||||
}
|
||||
getLogger().log(debugLevel, "zCenter: " + zCenter);
|
||||
} else if(args[i].equalsIgnoreCase("-l") || args[i].equalsIgnoreCase("-loaded")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
loadedChunksOnly = true;
|
||||
}
|
||||
getLogger().log(debugLevel, "Loaded only");
|
||||
} else if(args[i].equalsIgnoreCase("-c") || args[i].equalsIgnoreCase("-cooldown")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " The " + args[i] + " option needs an argument (" + args[i] + " value)!");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
cooldowntime = Integer.parseInt(args[i+1]);
|
||||
coption = true;
|
||||
i++;
|
||||
} catch(NumberFormatException e) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Your input contains a invalid number in the " + args[i] + " option!");
|
||||
return true;
|
||||
}
|
||||
getLogger().log(debugLevel, "cooldowntime: " + cooldowntime);
|
||||
} else if(args[i].equalsIgnoreCase("-f") || args[i].equalsIgnoreCase("-force")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
forceBlocks = true;
|
||||
forceRegions = true;
|
||||
} else {
|
||||
if(args[i+1].equalsIgnoreCase("blocks")) {
|
||||
forceBlocks = true;
|
||||
} else if(args[i+1].equalsIgnoreCase("regions")) {
|
||||
forceRegions = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
getLogger().log(debugLevel, "forceBlocks: " + forceBlocks);
|
||||
getLogger().log(debugLevel, "forceRegions: " + forceRegions);
|
||||
} else if(args[i].equalsIgnoreCase("-sp") || args[i].equalsIgnoreCase("-spawnpoint")) {
|
||||
if(i+1 >= args.length || args[i+1].startsWith("-")) {
|
||||
setSpawnpoint = 1;
|
||||
} else {
|
||||
if(args[i+1].equalsIgnoreCase("true")) {
|
||||
setSpawnpoint = 2;
|
||||
} else if(args[i+1].equalsIgnoreCase("false")) {
|
||||
setSpawnpoint = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
getLogger().log(debugLevel, "setSpawnpoint: " + setSpawnpoint);
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Your input contains an invalid option (" + args[i] + ")!");
|
||||
getLogger().log(debugLevel, "invalid: " + args[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//getLogger().info("Success: Parsed options");
|
||||
|
||||
if(playername.equalsIgnoreCase("CONSOLE")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Silly filly! The console can not teleport! Did you forgot to add the -player <playername> option?");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(world == null) {
|
||||
if(sender instanceof Player) {
|
||||
world = ((Player) sender).getWorld();
|
||||
} else if(sender instanceof BlockCommandSender) {
|
||||
world = ((BlockCommandSender) sender).getBlock().getWorld();
|
||||
} else if(sender instanceof ConsoleCommandSender) {
|
||||
world = player.getWorld();
|
||||
} else {
|
||||
world = player.getWorld();
|
||||
}
|
||||
}
|
||||
|
||||
if(world.getEnvironment() == Environment.NETHER && !forceBlocks) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " RandomTeleport currently does not work in the nether!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(playerlock.contains(player.getUniqueId())) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " RandomTeleport already tries to teleport this player!");
|
||||
return true;
|
||||
}
|
||||
playerlock.add(player.getUniqueId());
|
||||
|
||||
|
||||
//getLogger().info("Starting to read cooldown hashmap");
|
||||
|
||||
String cooldownid = player.getUniqueId().toString() + minRange + maxRange + xCenter + zCenter + cooldowntime + forceBlocks + forceRegions + setSpawnpoint;
|
||||
if(cooldown.containsKey(cooldownid) && cooldown.get(cooldownid) + cooldowntime * 1000 > System.currentTimeMillis()) {
|
||||
|
||||
// convert seconds in dhms format
|
||||
long cooldown_seconds = (cooldown.get(cooldownid)/1000 + cooldowntime - System.currentTimeMillis()/1000) + 1;
|
||||
String cooldown_text = "";
|
||||
|
||||
int cooldown_days = (int) (cooldown_seconds / 86400);
|
||||
if(cooldown_days > 0) {
|
||||
cooldown_seconds = cooldown_seconds - 86400 * cooldown_days;
|
||||
}
|
||||
|
||||
int cooldown_hours = (int) (cooldown_seconds / 3600);
|
||||
if(cooldown_hours > 0) {
|
||||
cooldown_seconds = cooldown_seconds - 3600 * cooldown_hours;
|
||||
}
|
||||
|
||||
int cooldown_minutes = (int) (cooldown_seconds / 60);
|
||||
if(cooldown_minutes > 0) {
|
||||
cooldown_seconds = cooldown_seconds - 60 * cooldown_minutes;
|
||||
}
|
||||
|
||||
if(cooldown_days > 0) {
|
||||
cooldown_text = cooldown_days + "d ";
|
||||
}
|
||||
|
||||
if(cooldown_hours > 0) {
|
||||
cooldown_text = cooldown_text + cooldown_hours + "h ";
|
||||
}
|
||||
|
||||
if(cooldown_minutes > 0) {
|
||||
cooldown_text = cooldown_text + cooldown_minutes + "m ";
|
||||
}
|
||||
|
||||
if(cooldown_seconds > 0) {
|
||||
cooldown_text = cooldown_text + cooldown_seconds + "s ";
|
||||
}
|
||||
|
||||
// display cooldown
|
||||
if(playername.equalsIgnoreCase("CONSOLE")) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " This teleport is on cooldown for player " + player.getName() + "!");
|
||||
}
|
||||
player.sendMessage(getTranslation("error.cooldown", ImmutableMap.of("cooldown_text", cooldown_text)));
|
||||
playerlock.remove(player.getUniqueId());
|
||||
return true;
|
||||
}
|
||||
|
||||
player.sendMessage(getTranslation("search", ImmutableMap.of("worldname", world.getName())));
|
||||
|
||||
// set center coordinates to player location
|
||||
if(!xoption) {
|
||||
xCenter = (int) player.getLocation().getX();
|
||||
}
|
||||
if(!zoption) {
|
||||
zCenter = (int) player.getLocation().getZ();
|
||||
}
|
||||
|
||||
getLogger().log(debugLevel, "RandomTeleport for player '" + playername + "' with minRange " + minRange + " maxRange " + maxRange + " xCenter " + xCenter + " zCenter " + zCenter + " forceBlocks=" + forceBlocks + " forceRegions=" + forceRegions);
|
||||
if(biomeList.size() > 0) {
|
||||
getLogger().log(Level.INFO, "Biomelist:");
|
||||
for(Biome biome : biomeList) {
|
||||
getLogger().log(Level.INFO, " " + biome);
|
||||
}
|
||||
}
|
||||
|
||||
int x;
|
||||
int z;
|
||||
int zold = 0;
|
||||
int xold = 0;
|
||||
int chunksum = 0;
|
||||
int chunksumold = 0;
|
||||
|
||||
List<Integer[]> chunklist = new ArrayList<Integer[]>();
|
||||
|
||||
if(loadedChunksOnly)
|
||||
for(Chunk c : world.getLoadedChunks())
|
||||
if(Math.abs(c.getX()) * 16 <= xCenter + maxRange && Math.abs(c.getZ()) * 16 <= zCenter + maxRange && (Math.abs(c.getX()) * 16 >= xCenter + minRange || Math.abs(c.getZ()) * 16 >= zCenter + minRange))
|
||||
chunklist.add(new Integer[]{c.getX(), c.getZ()});
|
||||
|
||||
for(int chunkcount = 0; chunkcount < 10 && chunksum < 81; chunkcount ++) {
|
||||
int count = 0;
|
||||
do {
|
||||
count++;
|
||||
Random r = new Random();
|
||||
|
||||
if(loadedChunksOnly) {
|
||||
int chunknumber = r.nextInt(chunklist.size());
|
||||
x = chunklist.get(chunknumber)[0] * 16 + r.nextInt(15);
|
||||
z = chunklist.get(chunknumber)[1] * 16 + r.nextInt(15);
|
||||
} else {
|
||||
int xRange;
|
||||
int zRange;
|
||||
//get random range in min and max range
|
||||
if (r.nextBoolean()) {
|
||||
xRange = minRange + r.nextInt(maxRange - minRange);
|
||||
zRange = r.nextInt(maxRange);
|
||||
} else {
|
||||
xRange = r.nextInt(maxRange);
|
||||
zRange = minRange + r.nextInt(maxRange - minRange);
|
||||
}
|
||||
|
||||
//make range negative with a 50% chance
|
||||
if (r.nextBoolean()) xRange = 0 - xRange;
|
||||
if (r.nextBoolean()) zRange = 0 - zRange;
|
||||
|
||||
x = xCenter + xRange;
|
||||
z = zCenter + zRange;
|
||||
}
|
||||
|
||||
if(count == 100) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " RandomTeleport could not find a save location!");
|
||||
if(!sender.getName().equalsIgnoreCase(player.getName())){
|
||||
player.sendMessage(getTranslation("error.location"));
|
||||
}
|
||||
getLogger().log(Level.INFO, "Error: RandomTeleport could not find a save location after " + count + " tries for the player '" + playername + "' (minRange " + minRange + " maxRange " + maxRange + " xCenter " + xCenter + " zCenter " + zCenter + " forceBlocks=" + forceBlocks + " forceRegions=" + forceRegions + ")");
|
||||
if(biomeList.size() > 0) {
|
||||
getLogger().log(Level.INFO, "Biomelist:");
|
||||
for(Biome biome : biomeList) {
|
||||
getLogger().log(Level.INFO, " " + biome);
|
||||
}
|
||||
}
|
||||
checkstat[count-1] = checkstat[count-1]++;
|
||||
playerlock.remove(player.getUniqueId());
|
||||
return true;
|
||||
}
|
||||
} while(!teleportCheck(player,world,x,z,biomeList, forceBlocks, forceRegions));
|
||||
|
||||
checkstat[count-1] = checkstat[count-1] + 1;
|
||||
|
||||
// if in force mode don't check chunks around location
|
||||
|
||||
if(chunkcount == 0) {
|
||||
xold = x;
|
||||
zold = z;
|
||||
}
|
||||
|
||||
if(forceRegions) {
|
||||
break;
|
||||
}
|
||||
|
||||
//(re)set sum of valid chunks to zero
|
||||
chunksum = 0;
|
||||
|
||||
// checks a square of 9x9 chunks around the random position for protected regions
|
||||
if(worldguard || factionsApiVersion > 0 || griefprevention || clancontrol) {
|
||||
for(int i = -4; i <= 4; i++) {
|
||||
for(int j = -4; j <= 4; j++) {
|
||||
int xcheck = x + i * 16;
|
||||
int zcheck = z + j * 16;
|
||||
Location location = new Location(world, xcheck, world.getHighestBlockYAt(xcheck, zcheck), zcheck);
|
||||
if(checkforRegion(player,location, false)) chunksum++;
|
||||
|
||||
}
|
||||
}
|
||||
getLogger().log(debugLevel, "RandomTeleport (" + chunkcount + ". try) found " + chunksum + " unprotected chunks around the location " + x + "/" + z);
|
||||
|
||||
|
||||
// if more not protected chunks were found then at the last random location:
|
||||
// --> save the position to xold and zold and the chunksum to chunksumold
|
||||
// --> xold/zold hold the coords of the location with the least protected chunks around it
|
||||
if(chunksum > chunksumold) {
|
||||
xold = x;
|
||||
zold = z;
|
||||
chunksumold = chunksum;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// break the loop and use the x/z values with the highest sum of non proteted chunks
|
||||
// if there is no location after 10 tries found which has no protected regions in a 15x15 square around the location
|
||||
// or
|
||||
// aborts if all 225 around the location are not protected
|
||||
}
|
||||
x = xold;
|
||||
z = zold;
|
||||
|
||||
// attempts to teleport player, sends message if it fails
|
||||
if(!teleportPlayer(playername,x,z,world,setSpawnpoint)) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Error:" + ChatColor.RED + " Player '" + playername + "' is not online anymore!");
|
||||
} else {
|
||||
getLogger().log(debugLevel, "Used teleport location X: " + x + " Z: " + z + " for player '" + playername + "' RandomTeleportID: " + cooldownid);
|
||||
}
|
||||
if(coption && !player.hasPermission("randomteleport.cooldownexempt")){
|
||||
cooldown.put(cooldownid, System.currentTimeMillis());
|
||||
writeMap(cooldown, "cooldown.map");
|
||||
//getLogger().info("Saved cooldown");
|
||||
}
|
||||
playerlock.remove(player.getUniqueId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Teleports player with the name playername at the highest block at x/z
|
||||
* @param playername The name of the player
|
||||
* @param x Coordinate of the block as int
|
||||
* @param z Coordinate of the block as int
|
||||
* @param world The world we should teleport the player to
|
||||
* @param setSpawnpoint if we should set the player's spawnpoint to the location (1, 2 = force) or not (0)
|
||||
* @return true if player got teleported
|
||||
*/
|
||||
|
||||
private boolean teleportPlayer(String playername, int x ,int z, World world, int setSpawnpoint) {
|
||||
final Player player = Bukkit.getServer().getPlayer(playername);
|
||||
if(player != null && world != null) {
|
||||
final int yTp = world.getHighestBlockYAt(x, z);
|
||||
Location loc = new Location(world, x + 0.5, yTp + 0.5, z + 0.5);
|
||||
player.teleport(loc);
|
||||
player.sendMessage(getTranslation("teleport", ImmutableMap.of("x", Integer.toString(x), "y", Integer.toString(yTp), "z", Integer.toString(z))));
|
||||
if(setSpawnpoint == 2 || (setSpawnpoint == 1 && player.getBedSpawnLocation() == null)) {
|
||||
player.setBedSpawnLocation(loc, true);
|
||||
player.sendMessage(getTranslation("setspawnpoint"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if block is valid to teleport to (no lava, fire, water, ...)
|
||||
* @param player The player we should check
|
||||
* @param world The world the coordinate is in
|
||||
* @param x Coordinate of the block as int
|
||||
* @param z Coordinate of the block as int
|
||||
* @param biomeList THe list of biomes at that point
|
||||
* @param forceBlocks true if should only check if the player wont die,
|
||||
* false for block restrictions check
|
||||
* @param forceRegions true if should not check if location is in region,
|
||||
* false for region restriction
|
||||
* @return true if the block is a valid teleport block
|
||||
*/
|
||||
|
||||
private boolean teleportCheck(Player player, World world, int x, int z, List<Biome> biomeList, boolean forceBlocks, boolean forceRegions) {
|
||||
if(worldborder) {
|
||||
WorldBorder wbPlugin = (WorldBorder) getServer().getPluginManager().getPlugin("WorldBorder");
|
||||
BorderData border = wbPlugin.getWorldBorder(world.getName());
|
||||
if(border != null && !border.insideBorder(x, z)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
org.bukkit.WorldBorder wb = world.getWorldBorder();
|
||||
double wbMaxX = wb.getCenter().getX() + wb.getSize() / 2;
|
||||
double wbMinX = wb.getCenter().getX() - wb.getSize() / 2;
|
||||
double wbMaxZ = wb.getCenter().getZ() + wb.getSize() / 2;
|
||||
double wbMinZ = wb.getCenter().getZ() - wb.getSize() / 2;
|
||||
|
||||
if(x > wbMaxX || x < wbMinX) {
|
||||
return false;
|
||||
}
|
||||
if(z > wbMaxZ || z < wbMinZ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int y = world.getHighestBlockYAt(x, z);
|
||||
Block highest = world.getBlockAt(x, y - 1, z);
|
||||
|
||||
getLogger().log(debugLevel, "Checked teleport location for player '" + player.getName() + "' X: " + x + " Y: " + (y - 1) + " Z: " + z + " is " + highest.getType() + " + " + world.getBlockAt(x, y + 1, z).getType() + ", Biome: " + highest.getBiome().toString());
|
||||
|
||||
if(biomeList.size() > 0 && !biomeList.contains(highest.getBiome())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!forceBlocks) {
|
||||
switch (world.getEnvironment()) {
|
||||
case NETHER:
|
||||
return false;
|
||||
case THE_END:
|
||||
if(highest.getType() == Material.AIR || highest.getType() == Material.WATER || highest.getType() == Material.STATIONARY_WATER || highest.getType() == Material.STATIONARY_LAVA || highest.getType() == Material.WEB || highest.getType() == Material.LAVA || highest.getType() == Material.CACTUS || highest.getType() == Material.ENDER_PORTAL || highest.getType() == Material.PORTAL)
|
||||
return false;
|
||||
case NORMAL:
|
||||
default:
|
||||
if(highest.getType() != Material.SAND && highest.getType() != Material.GRAVEL && highest.getType() != Material.DIRT && highest.getType() != Material.GRASS)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(highest.getType() == Material.AIR || highest.getType() == Material.WATER || highest.getType() == Material.STATIONARY_WATER || highest.getType() == Material.STATIONARY_LAVA || highest.getType() == Material.WEB || highest.getType() == Material.LAVA || highest.getType() == Material.CACTUS || highest.getType() == Material.ENDER_PORTAL || highest.getType() == Material.PORTAL)
|
||||
return false;
|
||||
}
|
||||
return checkforRegion(player, highest.getLocation(), forceRegions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can build at the highest block of the location
|
||||
* @param player The Player to check with
|
||||
* @param location the black at the location to check
|
||||
* @param forceRegions true if should not check if location is in region,
|
||||
* false for region restriction
|
||||
* @return true or false
|
||||
*/
|
||||
//
|
||||
private boolean checkforRegion(Player player, Location location, boolean forceRegions) {
|
||||
if(!forceRegions) {
|
||||
Block block = location.getWorld().getBlockAt(location);
|
||||
|
||||
BlockCanBuildEvent canBuildEvent = new BlockCanBuildEvent(block, block.getTypeId(), true);
|
||||
getServer().getPluginManager().callEvent(canBuildEvent);
|
||||
if(!canBuildEvent.isBuildable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(worldguard && !com.sk89q.worldguard.bukkit.WGBukkit.getPlugin().canBuild(player, block)) {
|
||||
return false;
|
||||
}
|
||||
if(griefprevention && GriefPrevention.instance.dataStore.getClaimAt(location, true, null) != null) {
|
||||
return false;
|
||||
}
|
||||
if(clancontrol) {
|
||||
boolean chunkOccupied = ClanControl.getInstance().getRegionManager().getChunk(location) != null;
|
||||
Region region = ClanControl.getInstance().getRegionManager().getRegion(location);
|
||||
if(chunkOccupied || (region != null && region.getStatus() != RegionStatus.FREE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(factionsApiVersion == 27) {
|
||||
com.massivecraft.factions.entity.Faction faction = com.massivecraft.factions.entity.BoardColl.get().getFactionAt(com.massivecraft.massivecore.ps.PS.valueOf(block));
|
||||
if(faction != com.massivecraft.factions.entity.FactionColl.get().getNone()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(factionsApiVersion == 26) {
|
||||
com.massivecraft.factions.entity.Faction faction = com.massivecraft.factions.entity.BoardColls.get().getFactionAt(com.massivecraft.massivecore.ps.PS.valueOf(block));
|
||||
if(faction != com.massivecraft.factions.entity.FactionColls.get().getForWorld(location.getWorld().getName()).getNone()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(factionsApiVersion == 16) {
|
||||
com.massivecraft.factions.Faction faction = com.massivecraft.factions.Board.getInstance().getFactionAt(new com.massivecraft.factions.FLocation(location));
|
||||
if(faction != com.massivecraft.factions.Factions.getInstance().getNone()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Hashmap to a file
|
||||
* @param object The Hashmap to write
|
||||
* @param outputFile The file to write to
|
||||
*/
|
||||
public void writeMap(Object object, String outputFile) {
|
||||
try {
|
||||
File file = new File(getDataFolder(), outputFile);
|
||||
if (!file.isFile()) {
|
||||
if(!file.createNewFile()){
|
||||
throw new IOException("Error creating new file: " + file.getPath());
|
||||
}
|
||||
}
|
||||
FileOutputStream fileOut = new FileOutputStream(file.getPath());
|
||||
ObjectOutputStream out = new ObjectOutputStream(fileOut);
|
||||
out.writeObject(object);
|
||||
out.close();
|
||||
fileOut.close();
|
||||
getLogger().fine("Serialized data is saved in " + file.getPath());
|
||||
} catch(IOException i) {
|
||||
i.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a Hashmap from a file
|
||||
* @param inputFile The file to read from
|
||||
* @return An Object which is a HashMap<Object,Object>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object readMap(String inputFile) {
|
||||
HashMap<Object, Object> map = new HashMap<Object,Object>();
|
||||
File file = new File(getDataFolder(), inputFile);
|
||||
if (!file.isFile()) {
|
||||
getLogger().log(Level.INFO, "No file found in " + file.getPath());
|
||||
try {
|
||||
if(!file.createNewFile()) {
|
||||
throw new IOException("Error while creating new file: " + file.getPath());
|
||||
} else {
|
||||
writeMap(map, inputFile);
|
||||
getLogger().log(Level.INFO, "New file created in " + file.getPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
FileInputStream fileIn = new FileInputStream(file.getPath());
|
||||
ObjectInputStream in = new ObjectInputStream(fileIn);
|
||||
map = (HashMap<Object, Object>) in.readObject();
|
||||
in.close();
|
||||
fileIn.close();
|
||||
getLogger().log(Level.INFO, "Sucessfully loaded cooldown.map.");
|
||||
} catch(IOException i) {
|
||||
getLogger().log(Level.WARNING, "No saved Map found in " + inputFile);
|
||||
} catch(ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string is mumeric
|
||||
* @param str to test
|
||||
* @return True if input string is numeric
|
||||
*/
|
||||
public static boolean isNumeric(String str) {
|
||||
for (char c : str.toCharArray()) {
|
||||
if (!Character.isDigit(c)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getTranslation(String key) {
|
||||
if(getConfig().getString("msg." + key, "").isEmpty()) {
|
||||
return ChatColor.RED + "Unknown language key: " + ChatColor.YELLOW + key;
|
||||
} else {
|
||||
return ChatColor.translateAlternateColorCodes('&', getConfig().getString("msg." + key));
|
||||
}
|
||||
}
|
||||
|
||||
public String getTranslation(String key, Map<String, String> replacements) {
|
||||
String string = getTranslation(key);
|
||||
|
||||
// insert replacements
|
||||
if(replacements != null)
|
||||
for(String variable : replacements.keySet())
|
||||
string = string.replaceAll("\\{"+variable+"\\}", replacements.get(variable));
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
debug: false
|
||||
# Triggered when you use /rtp without any additional paramters
|
||||
# Just write your command as you would use it ingame here
|
||||
# Don't use the -p parameter, this will get added automaticly with the senders name/the specified playername
|
||||
presets:
|
||||
default: "/rtp 100 1000 -f"
|
||||
# add more to use /rtp <rtpname>, player needs "randomteleport.presets.<rtpname>"
|
||||
# <rtpname>: "/rtp 1 2"
|
||||
test: "rtp 10 200 -f"
|
||||
|
||||
msg:
|
||||
search: "&7RandomTeleport searches for a safe place in world {worldname}. . ."
|
||||
teleport: "&7RandomTeleport teleported you to X: {x} Y: {y} Z: {z}!"
|
||||
setspawnpoint: "&7Your Respawnpoint has been set to your current location!"
|
||||
error:
|
||||
location: "&4Error: &cRandomTeleport could not find a save location!"
|
||||
cooldown: "&cYou have to wait {cooldown_text}before using this RandomTeleport again!"
|
|
@ -1,60 +0,0 @@
|
|||
name: RandomTeleport
|
||||
main: de.themoep.bukkit.plugin.RandomTeleport.RandomTeleport
|
||||
softdepend: [WorldGuard,Factions,GriefPrevention,ClanControl,WorldBorder]
|
||||
version: '${minecraft.plugin.version}'
|
||||
description: provides a command to teleport the player to a random save location
|
||||
author: Phoenix616
|
||||
website: http://dev.bukkit.org/bukkit-plugins/randomteleport/
|
||||
commands:
|
||||
randomteleport:
|
||||
aliases: [randomtp, rtp]
|
||||
description: RandomTeleport command.
|
||||
usage: |
|
||||
/<command> - uses the default preset
|
||||
/<command> <preset> [<playername>]- uses a specific preset
|
||||
/<command> <minRange> <maxRange> [-p, -w, -x, -z, -c, -f]
|
||||
minRange - minimum distance to the center point (square shaped)
|
||||
maxRange - maximum distance to the center point (square shaped)
|
||||
Options:
|
||||
> -p,-player <playername> - teleports other players
|
||||
> -w,-world <worldname> - teleports the player in a specific world
|
||||
> -b,-biome <biomename> [<biome 2> ...] - only teleport to this biome (multiple allowed, Bukkit biome names!)
|
||||
> -x,-xPos <x value> - x axis of the center point, if not set the player's x axis is used
|
||||
> -z,-zPos <z value> - z axis of the center point, if not set the player's z axis is used
|
||||
> -l,-loaded - only search loaded chunks for possible locations
|
||||
> -c, -cooldown <seconds> - cooldown in seconds after which the player can use this teleporter again
|
||||
> -f,-force - teleport even if there is no dirt/grass/sand/gravel, only checks for lava/water/cactus, ignores WorldGuard/Faction regions
|
||||
> -f,-force [<blocks|regions>] - only ignore blocks or regions
|
||||
/<command> stat - shows a statistic of the teleports since the last restart
|
||||
/<command> reload - reloads the config
|
||||
permissions:
|
||||
randomteleport.use:
|
||||
description: Gives permission to the command
|
||||
default: op
|
||||
randomteleport.tpothers:
|
||||
description: Gives permission to teleport other players
|
||||
default: op
|
||||
randomteleport.cooldownexempt:
|
||||
description: Teleportcooldown does not effect these players
|
||||
default: op
|
||||
randomteleport.stat:
|
||||
description: Permission for showing the teleport statistic
|
||||
default: op
|
||||
randomteleport.reload:
|
||||
description: Permission to use the reload command
|
||||
default: op
|
||||
randomteleport.presets.default:
|
||||
description: Gives permission to use the default random teleport preset
|
||||
default: op
|
||||
randomteleport.presets.*:
|
||||
description: Gives permission to use all random teleport presets
|
||||
default: op
|
||||
randomteleport.sign.preset.default:
|
||||
description: Gives permission to use the default preset with a rightclick on a preset sign
|
||||
default: op
|
||||
randomteleport.sign.preset.*:
|
||||
description: Gives permission to use all presets with a rightclick on a preset sign
|
||||
default: op
|
||||
randomteleport.sign.create:
|
||||
description: Allows to create and destroy preset signs ([rtp] or [RandomTP] on the 2nd line and the preset name on the 3rd)
|
||||
default: op
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.themoep.randomteleport</groupId>
|
||||
<artifactId>randomteleport-parent</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<description>Randomly teleport players on your server!</description>
|
||||
<name>FUBSRandomTeleport</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<build.number>${buildNumber}</build.number>
|
||||
<minecraft.plugin.name>RandomTeleport</minecraft.plugin.name>
|
||||
<minecraft.plugin.version>${project.version} ${buildDescription}</minecraft.plugin.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<url>https://moep.tv/licenses/gpl-v3.txt</url>
|
||||
<name>GPLv3</name>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<modules>
|
||||
<module>randomteleport-hook</module>
|
||||
<module>randomteleport-plugin-hooks</module>
|
||||
<module>randomteleport-plugin</module>
|
||||
</modules>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>paper-repo</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minebench-repo</id>
|
||||
<url>https://repo.minebench.de/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.16.5-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
<version>1.0.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.themoep</groupId>
|
||||
<artifactId>minedown</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.themoep.utils</groupId>
|
||||
<artifactId>lang-bukkit</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>static_build_number</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildNumber>0</buildNumber>
|
||||
<buildDescription>(compiled at ${maven.build.timestamp})</buildDescription>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dynamic_build_number</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildNumber>${env.BUILD_NUMBER}</buildNumber>
|
||||
<buildDescription>(build ${env.BUILD_NUMBER})</buildDescription>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>randomteleport-parent</artifactId>
|
||||
<groupId>de.themoep.randomteleport</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>randomteleport-hook</artifactId>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,182 @@
|
|||
package de.themoep.randomteleport.hook;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HookManager implements Listener, ProtectionHook, WorldborderHook {
|
||||
private final Plugin plugin;
|
||||
|
||||
private Map<String, PluginHook> hookMap = new LinkedHashMap<>();
|
||||
|
||||
public HookManager(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
hookMap.put("Vanilla Minecraft", new MinecraftHook(plugin));
|
||||
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
for (Plugin p : plugin.getServer().getPluginManager().getPlugins()) {
|
||||
if (p.isEnabled()) {
|
||||
registerHook(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerHook(Plugin plugin) {
|
||||
String path = getClass().getPackage().getName() + ".plugin." + plugin.getName();
|
||||
String version = plugin.getDescription().getVersion().replace('.', '_').replace('-', '_');
|
||||
Class<?> hookClass = null;
|
||||
do {
|
||||
try {
|
||||
hookClass = Class.forName(path + version + "Hook");
|
||||
if (!PluginHook.class.isAssignableFrom(hookClass)) {
|
||||
hookClass = null;
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
if (version.contains("_")) {
|
||||
version = version.substring(0, version.lastIndexOf('_'));
|
||||
} else {
|
||||
try {
|
||||
hookClass = Class.forName(path + "Hook");
|
||||
if (!PluginHook.class.isAssignableFrom(hookClass)) {
|
||||
hookClass = null;
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
break;
|
||||
}
|
||||
} while (hookClass == null);
|
||||
|
||||
if (hookClass != null) {
|
||||
try {
|
||||
PluginHook hook = (PluginHook) hookClass.getConstructor().newInstance();
|
||||
if (hook instanceof Listener) {
|
||||
getPlugin().getServer().getPluginManager().registerEvents((Listener) hook, getPlugin());
|
||||
}
|
||||
hookMap.put(plugin.getName(), hook);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Could not hook into " + plugin.getName() + " " + plugin.getDescription().getVersion() + "!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
registerHook(event.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
PluginHook hook = hookMap.remove(event.getPlugin().getName());
|
||||
if (hook instanceof Listener) {
|
||||
hook.unregisterEvents();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return plugin.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all hooks of a certain type, hooks registered later override hooks registered before them
|
||||
* @param hookClass The type of hook to get
|
||||
* @param <T> The type of hook to get
|
||||
* @return A list of hooks, empty if there are none
|
||||
*/
|
||||
public <T extends PluginHook> List<T> getHooks(Class<T> hookClass) {
|
||||
List<T> list = hookMap.values().stream().filter(hookClass::isInstance).map(h -> (T) h).collect(Collectors.toList());
|
||||
Collections.reverse(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Convenience methods to check all registered hooks
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
for (ProtectionHook hook : getHooks(ProtectionHook.class)) {
|
||||
if (!hook.canBuild(player, location)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
for (ProtectionHook hook : getHooks(ProtectionHook.class)) {
|
||||
if (!hook.canBuild(player, world, chunkX, chunkZ)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getCenter(World world) {
|
||||
for (WorldborderHook hook : getHooks(WorldborderHook.class)) {
|
||||
Location center = hook.getCenter(world);
|
||||
if (center != null) {
|
||||
return center;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBorderRadius(World world) {
|
||||
for (WorldborderHook hook : getHooks(WorldborderHook.class)) {
|
||||
double radius = hook.getBorderRadius(world);
|
||||
if (radius > 0) {
|
||||
return radius;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideBorder(Location location) {
|
||||
for (WorldborderHook hook : getHooks(WorldborderHook.class)) {
|
||||
if (!hook.isInsideBorder(location)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package de.themoep.randomteleport.hook;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Lockable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class MinecraftHook implements ProtectionHook, WorldborderHook {
|
||||
private final Plugin plugin;
|
||||
|
||||
public MinecraftHook(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return "Vanilla Minecraft";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
BlockStateSnapshotResult state = PaperLib.getBlockState(location.getBlock(), false);
|
||||
if (state.getState() instanceof Lockable) {
|
||||
return ((Lockable) state.getState()).getLock() == null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getCenter(World world) {
|
||||
if (world.getWorldBorder() != null) {
|
||||
return world.getWorldBorder().getCenter();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBorderRadius(World world) {
|
||||
if (world.getWorldBorder() != null) {
|
||||
return world.getWorldBorder().getSize() / 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideBorder(Location location) {
|
||||
if (location.getWorld().getWorldBorder() != null) {
|
||||
return location.getWorld().getWorldBorder().isInside(location);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package de.themoep.randomteleport.hook;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public interface PluginHook {
|
||||
Plugin getPlugin();
|
||||
|
||||
String getPluginName();
|
||||
|
||||
default int getHookVersion() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
default void unregisterEvents() {};
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package de.themoep.randomteleport.hook;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface ProtectionHook extends PluginHook {
|
||||
|
||||
/**
|
||||
* Check if a player can build at a location
|
||||
*
|
||||
* @param player The player to check
|
||||
* @param location The location to check
|
||||
* @return Whether or not the player can build
|
||||
*/
|
||||
boolean canBuild(Player player, Location location);
|
||||
|
||||
/**
|
||||
* Check if a player can build in a chunk
|
||||
* @param player The player to check
|
||||
* @param chunk The chunk to check
|
||||
* @return Whether or not the player can build
|
||||
*/
|
||||
default boolean canBuild(Player player, Chunk chunk) {
|
||||
return canBuild(player, chunk.getWorld(), chunk.getX(), chunk.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can build in a chunk
|
||||
* @param player The player to check
|
||||
* @param world The chunk's world
|
||||
* @param chunkX The chunk's X coordinate
|
||||
* @param chunkZ The chunk's Z coordinate
|
||||
* @return Whether or not the player can build
|
||||
*/
|
||||
boolean canBuild(Player player, World world, int chunkX, int chunkZ);
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package de.themoep.randomteleport.hook;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
public interface WorldborderHook extends PluginHook {
|
||||
|
||||
/**
|
||||
* Get the center of the world border
|
||||
* @param world The world to get the border center for
|
||||
* @return The center or null if there is no border
|
||||
*/
|
||||
Location getCenter(World world);
|
||||
|
||||
/**
|
||||
* Get the radius of the world border
|
||||
* @param world The world to get the border radius for
|
||||
* @return The radius or -1 if there is no border
|
||||
*/
|
||||
double getBorderRadius(World world);
|
||||
|
||||
/**
|
||||
* Convenience method to check if a location is inside the border
|
||||
* @param location The location to check
|
||||
* @return True if it is inside (or there is no border), false if not
|
||||
*/
|
||||
boolean isInsideBorder(Location location);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>chunkyborder</artifactId>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>codemc</id>
|
||||
<url>https://repo.codemc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.popcraft</groupId>
|
||||
<artifactId>chunkyborder-bukkit</artifactId>
|
||||
<version>1.1.42</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.popcraft</groupId>
|
||||
<artifactId>chunky-bukkit</artifactId>
|
||||
<version>1.3.52</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,47 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
import de.themoep.randomteleport.hook.WorldborderHook;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.popcraft.chunkyborder.BorderData;
|
||||
import org.popcraft.chunkyborder.ChunkyBorder;
|
||||
|
||||
public class ChunkyBorderHook implements WorldborderHook {
|
||||
private final Plugin plugin;
|
||||
private final ChunkyBorder chunkyBorder;
|
||||
|
||||
public ChunkyBorderHook() {
|
||||
this.plugin = Bukkit.getPluginManager().getPlugin("ChunkyBorder");
|
||||
chunkyBorder = plugin.getServer().getServicesManager().getRegistration(ChunkyBorder.class).getProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getCenter(World world) {
|
||||
BorderData borderData = chunkyBorder.getBorders().get(world.getName());
|
||||
return borderData != null ? new Location(world, borderData.getCenterX(),0D,borderData.getCenterZ()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBorderRadius(World world) {
|
||||
BorderData borderData = chunkyBorder.getBorders().get(world.getName());
|
||||
return borderData != null ? borderData.getRadiusX() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideBorder(Location location) {
|
||||
BorderData borderData = chunkyBorder.getBorders().get(location.getWorld().getName());
|
||||
return borderData == null || borderData.getBorder().isBounding(location.getBlockX(),location.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return plugin.getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>factions-uuid</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>factions-repo</id>
|
||||
<url>https://ci.ender.zone/plugin/repository/everything/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft</groupId>
|
||||
<artifactId>Factions</artifactId>
|
||||
<version>1.6.9.5-U0.2.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,57 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - Factions UUID Hook
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.massivecraft.factions.Board;
|
||||
import com.massivecraft.factions.FLocation;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class Factions1_6_9_5_U0Hook implements ProtectionHook {
|
||||
|
||||
private final Plugin inst;
|
||||
|
||||
public Factions1_6_9_5_U0Hook() {
|
||||
inst = Bukkit.getPluginManager().getPlugin("Factions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
return Board.getInstance().getFactionAt(new FLocation(location)) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return Board.getInstance().getFactionAt(new FLocation(world.getName(), chunkX, chunkZ)) == null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>factions</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>minebench-repo</id>
|
||||
<url>https://repo.minebench.de/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft.factions</groupId>
|
||||
<artifactId>factions</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft.massivecore</groupId>
|
||||
<artifactId>massivecore</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,56 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - Factions Hook
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class Factions2Hook implements ProtectionHook {
|
||||
|
||||
private final Plugin inst;
|
||||
|
||||
public Factions2Hook() {
|
||||
inst = Bukkit.getPluginManager().getPlugin("Factions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
return BoardColl.get().getFactionAt(PS.valueOf(location)) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return BoardColl.get().getFactionAt(PS.valueOf(world.getName(), chunkX, chunkZ)) == null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>griefdefender</artifactId>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gdapi</id>
|
||||
<url>https://repo.glaremasters.me/repository/bloodshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.griefdefender</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>2.1.0-20220122.032038-5</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,46 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
import com.griefdefender.api.GriefDefender;
|
||||
import com.griefdefender.api.claim.ClaimManager;
|
||||
import com.griefdefender.api.claim.ClaimTypes;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class GriefDefenderHook implements ProtectionHook {
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return Bukkit.getPluginManager().getPlugin("GriefDefender");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return "GriefDefender";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
return canBuild(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return canBuild(world, chunkX * 16, world.getSeaLevel(), chunkZ * 16);
|
||||
}
|
||||
|
||||
private boolean canBuild(World world, int x, int y, int z) {
|
||||
if (GriefDefender.getCore().isEnabled(world.getUID())) {
|
||||
ClaimManager claimManager = GriefDefender.getCore().getClaimManager(world.getUID());
|
||||
if (claimManager == null) {
|
||||
return true;
|
||||
} else {
|
||||
return claimManager.getClaimAt(x, y, z).getType() == ClaimTypes.WILDERNESS;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ RandomTeleport - randomteleport-plugin-hooks - $project.description
|
||||
~ Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
~
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>griefprevention</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.TechFortress</groupId>
|
||||
<artifactId>GriefPrevention</artifactId>
|
||||
<version>16.12.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - GriefPrevention Hook
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import me.ryanhamshire.GriefPrevention.*;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class GriefPreventionHook implements ProtectionHook {
|
||||
|
||||
private final GriefPrevention inst;
|
||||
|
||||
public GriefPreventionHook() {
|
||||
inst = GriefPrevention.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
return inst.dataStore.getClaimAt(location, false, null) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
if (inst.claimsEnabledForWorld(world)) {
|
||||
for (Claim claim : inst.dataStore.getClaims(chunkX, chunkZ)) {
|
||||
if (claim.getLesserBoundaryCorner().getWorld().equals(world) && !player.getUniqueId().equals(claim.ownerID)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>randomteleport-parent</artifactId>
|
||||
<groupId>de.themoep.randomteleport</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>worldguard-6</module>
|
||||
<module>worldguard-7</module>
|
||||
<module>griefprevention</module>
|
||||
<module>griefdefender</module>
|
||||
<module>redprotect</module>
|
||||
<module>factions</module>
|
||||
<module>factions-uuid</module>
|
||||
<module>worldborder</module>
|
||||
<module>chunkyborder</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.themoep.randomteleport</groupId>
|
||||
<artifactId>randomteleport-hook</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>redprotect</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>redprotect-repo</id>
|
||||
<url>https://raw.githubusercontent.com/FabioZumbi12/RedProtect/mvn-repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>br.net.fabiozumbi12.RedProtect</groupId>
|
||||
<artifactId>RedProtect-Spigot</artifactId>
|
||||
<version>7.6.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>br.net.fabiozumbi12.RedProtect</groupId>
|
||||
<artifactId>RedProtect-Core</artifactId>
|
||||
<version>7.6.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - RedProtect Hook
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import br.net.fabiozumbi12.RedProtect.Bukkit.RedProtect;
|
||||
import br.net.fabiozumbi12.RedProtect.Bukkit.Region;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RedProtectHook implements ProtectionHook {
|
||||
|
||||
private final RedProtect inst;
|
||||
|
||||
public RedProtectHook() {
|
||||
inst = RedProtect.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
Region region = inst.getAPI().getRegion(location);
|
||||
return region == null || region.canBuild(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
for (Region region : inst.getAPI().getChunkRegions(world.getChunkAt(chunkX, chunkZ))) {
|
||||
if (!region.canBuild(player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>worldborder</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.Brettflan</groupId>
|
||||
<artifactId>WorldBorder</artifactId>
|
||||
<version>master-c5df3417c8-1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - worldborder - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.wimbli.WorldBorder.BorderData;
|
||||
import com.wimbli.WorldBorder.WorldBorder;
|
||||
import de.themoep.randomteleport.hook.WorldborderHook;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class WorldBorderHook implements WorldborderHook {
|
||||
private final WorldBorder plugin;
|
||||
|
||||
public WorldBorderHook() {
|
||||
plugin = WorldBorder.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getCenter(World world) {
|
||||
BorderData data = plugin.getWorldBorder(world.getName());
|
||||
return data == null ? null : new Location(world, data.getX(), 0, data.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBorderRadius(World world) {
|
||||
BorderData data = plugin.getWorldBorder(world.getName());
|
||||
return data == null ? -1 : Math.min(data.getRadiusX(), data.getRadiusZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideBorder(Location location) {
|
||||
BorderData data = plugin.getWorldBorder(location.getWorld().getName());
|
||||
return data == null || data.insideBorder(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return plugin.getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>worldguard-6</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sk89q-repo</id>
|
||||
<url>https://maven.sk89q.com/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldguard</artifactId>
|
||||
<version>6.1.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,55 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - worldguard-6 - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class WorldGuard6Hook implements ProtectionHook {
|
||||
|
||||
private final WorldGuardPlugin inst;
|
||||
|
||||
public WorldGuard6Hook() {
|
||||
inst = WorldGuardPlugin.inst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, Location location) {
|
||||
return inst.canBuild(player, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return canBuild(player, new Location(world, (double) chunkX * 16 + 8, world.getSeaLevel(), (double) chunkZ * 16 + 8));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>randomteleport-plugin-hooks</artifactId>
|
||||
<groupId>de.themoep.randomteleport.pluginhook</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>worldguard-7</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sk89q-repo</id>
|
||||
<url>https://maven.sk89q.com/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-legacy</artifactId>
|
||||
<version>7.0.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,65 @@
|
|||
package de.themoep.randomteleport.hook.plugin;
|
||||
|
||||
/*
|
||||
* RandomTeleport - worldguard-7 - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import de.themoep.randomteleport.hook.ProtectionHook;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class WorldGuard7Hook implements ProtectionHook {
|
||||
|
||||
private final WorldGuardPlugin inst;
|
||||
|
||||
public WorldGuard7Hook() {
|
||||
inst = WorldGuardPlugin.inst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return inst.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, org.bukkit.Location location) {
|
||||
return canBuild(WorldGuardPlugin.inst().wrapPlayer(player), BukkitAdapter.adapt(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(Player player, World world, int chunkX, int chunkZ) {
|
||||
return canBuild(WorldGuardPlugin.inst().wrapPlayer(player), new Location(
|
||||
BukkitAdapter.adapt(world), (double) chunkX * 16 + 8, world.getSeaLevel(), (double) chunkZ * 16 + 8)
|
||||
);
|
||||
}
|
||||
|
||||
private boolean canBuild(LocalPlayer player, Location location) {
|
||||
return WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testBuild(location, player, Flags.BUILD);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>randomteleport-parent</artifactId>
|
||||
<groupId>de.themoep.randomteleport</groupId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>randomteleport-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>paper-repo</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>randomteleport-hook</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}.pluginhook</groupId>
|
||||
<artifactId>worldguard-6</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}.pluginhook</groupId>
|
||||
<artifactId>worldguard-7</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}.pluginhook</groupId>
|
||||
<artifactId>worldborder</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}.pluginhook</groupId>
|
||||
<artifactId>chunkyborder</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}.pluginhook</groupId>
|
||||
<artifactId>griefdefender</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${minecraft.plugin.name}</finalName>
|
||||
<directory>../target/</directory>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>io.papermc.lib</pattern>
|
||||
<shadedPattern>de.themoep.randomteleport.libs.paperlib</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.themoep.minedown</pattern>
|
||||
<shadedPattern>de.themoep.randomteleport.libs.minedown</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.themoep.utils.lang</pattern>
|
||||
<shadedPattern>de.themoep.randomteleport.libs.lang</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,514 @@
|
|||
package de.themoep.randomteleport;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Table;
|
||||
import de.themoep.minedown.MineDown;
|
||||
import de.themoep.randomteleport.api.RandomTeleportAPI;
|
||||
import de.themoep.randomteleport.hook.HookManager;
|
||||
import de.themoep.randomteleport.listeners.SignListener;
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import de.themoep.randomteleport.searcher.options.*;
|
||||
import de.themoep.randomteleport.searcher.validators.BiomeValidator;
|
||||
import de.themoep.randomteleport.searcher.validators.BlockValidator;
|
||||
import de.themoep.randomteleport.searcher.validators.HeightValidator;
|
||||
import de.themoep.randomteleport.searcher.validators.LocationValidator;
|
||||
import de.themoep.randomteleport.searcher.validators.ProtectionValidator;
|
||||
import de.themoep.randomteleport.searcher.validators.WorldborderValidator;
|
||||
import de.themoep.utils.lang.bukkit.LanguageManager;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RandomTeleport extends JavaPlugin implements RandomTeleportAPI {
|
||||
|
||||
public static final Random RANDOM = new Random();
|
||||
private HookManager hookManager;
|
||||
private LanguageManager lang;
|
||||
private Table<String, UUID, Map.Entry<Long, Integer>> cooldowns = HashBasedTable.create();
|
||||
private Map<UUID, RandomSearcher> runningSearchers = new HashMap<>();
|
||||
|
||||
private ValidatorRegistry locationValidators = new ValidatorRegistry();
|
||||
private List<OptionParser> optionParsers = new ArrayList<>();
|
||||
|
||||
private Material[] safeBlocks;
|
||||
private Material[] unsafeBlocks;
|
||||
private Set<String> signVariables;
|
||||
|
||||
private boolean hasMinHeight = true;
|
||||
|
||||
public void onEnable() {
|
||||
hookManager = new HookManager(this);
|
||||
loadConfig();
|
||||
initOptionParsers();
|
||||
initValidators();
|
||||
getCommand("randomteleport").setExecutor(new RandomTeleportCommand(this));
|
||||
getServer().getPluginManager().registerEvents(new SignListener(this), this);
|
||||
}
|
||||
|
||||
public void loadConfig() {
|
||||
saveDefaultConfig();
|
||||
reloadConfig();
|
||||
List<String> safeBlocksList;
|
||||
if (getConfig().contains("save-blocks")) {
|
||||
safeBlocksList = getConfig().getStringList("save-blocks");
|
||||
} else {
|
||||
safeBlocksList = getConfig().getStringList("safe-blocks");
|
||||
}
|
||||
safeBlocks = safeBlocksList.stream()
|
||||
.map(s -> {
|
||||
Material mat = Material.matchMaterial(s);
|
||||
if (mat == null) {
|
||||
getLogger().log(Level.WARNING, "Error in safe blocks config! No material found with name " + s);
|
||||
}
|
||||
return mat;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(Material[]::new);
|
||||
List<String> unsafeBlocksList;
|
||||
if (getConfig().contains("unsave-blocks")) {
|
||||
unsafeBlocksList = getConfig().getStringList("unsave-blocks");
|
||||
} else {
|
||||
unsafeBlocksList = getConfig().getStringList("unsafe-blocks");
|
||||
}
|
||||
unsafeBlocks = unsafeBlocksList.stream()
|
||||
.map(s -> {
|
||||
Material mat = Material.matchMaterial(s);
|
||||
if (mat == null) {
|
||||
getLogger().log(Level.WARNING, "Error in unsafe blocks config! No material found with name " + s);
|
||||
}
|
||||
// Air was in the default for a while now but will cause issues. Don't allow that.
|
||||
if (mat == Material.AIR) {
|
||||
getLogger().log(Level.WARNING, "Your list of unsafe blocks contained 'air'!" +
|
||||
" This will cause issues and has not been loaded. Remove it from your config to remove this warning!");
|
||||
return null;
|
||||
}
|
||||
return mat;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(Material[]::new);
|
||||
signVariables = getConfig().getStringList("sign-variables").stream().map(String::toLowerCase).collect(Collectors.toSet());
|
||||
lang = new LanguageManager(this, getConfig().getString("lang"));
|
||||
}
|
||||
|
||||
private void initOptionParsers() {
|
||||
addOptionParser(new BooleanOptionParser("debug", (searcher) -> searcher.setDebug(true)));
|
||||
addOptionParser(new SimpleOptionParser(array("p", "player"), (searcher, args) -> {
|
||||
if (args.length > 0 && searcher.getInitiator().hasPermission("randomteleport.tpothers")) {
|
||||
List<Player> players = new ArrayList<>();
|
||||
for (String arg : args) {
|
||||
for (String s : arg.split(",")) {
|
||||
Player player = getServer().getPlayer(s);
|
||||
if (player == null) {
|
||||
throw new PlayerNotFoundException(s);
|
||||
}
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
searcher.getTargets().addAll(players);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("x", "xpos"), 1, (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.getCenter().setX(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("z", "zpos"), 1, (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.getCenter().setZ(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("miny"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setMinY(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("maxy"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setMaxY(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("w", "world"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
String[] worldNames = args[0].split(",");
|
||||
String worldName = worldNames[searcher.getRandom().nextInt(worldNames.length)];
|
||||
World world = getServer().getWorld(worldName);
|
||||
if (world == null) {
|
||||
throw new WorldNotFoundException(worldName);
|
||||
}
|
||||
searcher.setWorld(world);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("c", "cooldown"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setCooldown(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("f", "force"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
if ("regions".equalsIgnoreCase(args[0])) {
|
||||
searcher.getValidators().remove("protection");
|
||||
} else if ("blocks".equalsIgnoreCase(args[0])) {
|
||||
searcher.getValidators().add(new BlockValidator(false, unsafeBlocks));
|
||||
} else {
|
||||
throw new NotFoundException(args[0]);
|
||||
}
|
||||
} else {
|
||||
searcher.getValidators().remove("protection");
|
||||
searcher.getValidators().add(new BlockValidator(false, unsafeBlocks));
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("b", "biome"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
List<Biome> biomes = new ArrayList<>();
|
||||
for (String arg : args) {
|
||||
biomes.add(Biome.valueOf(arg.toUpperCase()));
|
||||
}
|
||||
if (!biomes.isEmpty()) {
|
||||
searcher.getValidators().add(new BiomeValidator(biomes.toArray(new Biome[0])));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("l", "loaded"), (searcher, args) -> {
|
||||
searcher.searchInLoadedOnly(true);
|
||||
return true;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("g", "generated"), (searcher, args) -> {
|
||||
searcher.searchInGeneratedOnly(true);
|
||||
return true;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("id"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setId(args[0]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser(array("t", "tries"), (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setMaxTries(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new SimpleOptionParser("checkdelay", (searcher, args) -> {
|
||||
if (args.length > 0) {
|
||||
searcher.setCheckDelay(Integer.parseInt(args[0]));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
addOptionParser(new AdditionalOptionParser("spawnpoint", "sp"));
|
||||
}
|
||||
|
||||
private void initValidators() {
|
||||
locationValidators.add(new WorldborderValidator());
|
||||
locationValidators.add(new HeightValidator(unsafeBlocks));
|
||||
locationValidators.add(new ProtectionValidator());
|
||||
locationValidators.add(new BlockValidator(safeBlocks));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of all running searchers
|
||||
* @return The map of running searchers
|
||||
*/
|
||||
public Map<UUID, RandomSearcher> getRunningSearchers() {
|
||||
return runningSearchers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to create arrays with a nicer syntax. Seriously, why does Java not just accept {"string"} as parameters?!?
|
||||
* @param array The array values
|
||||
* @return The same array
|
||||
*/
|
||||
private static <T> T[] array(T... array) {
|
||||
return array;
|
||||
}
|
||||
|
||||
public boolean sendMessage(Collection<? extends CommandSender> senders, String key, String... replacements) {
|
||||
boolean r = false;
|
||||
for (CommandSender sender : senders) {
|
||||
r |= sendMessage(sender, key, replacements);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean sendMessage(CommandSender sender, String key, String... replacements) {
|
||||
BaseComponent[] message = getComponentMessage(sender, key, replacements);
|
||||
if (message != null && message.length != 0) {
|
||||
sender.spigot().sendMessage(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public BaseComponent[] getComponentMessage(CommandSender sender, String key, String... replacements) {
|
||||
return new MineDown(getLang(sender, key))
|
||||
.placeholderPrefix("{")
|
||||
.placeholderSuffix("}")
|
||||
.replace(replacements)
|
||||
.toComponent();
|
||||
}
|
||||
|
||||
public String getTextMessage(CommandSender sender, String key, String... replacements) {
|
||||
return TextComponent.toLegacyText(getComponentMessage(sender, key, replacements));
|
||||
}
|
||||
|
||||
private String getLang(CommandSender sender, String key) {
|
||||
return lang.getConfig(sender).get(key);
|
||||
}
|
||||
|
||||
public HookManager getHookManager() {
|
||||
return hookManager;
|
||||
}
|
||||
|
||||
public ValidatorRegistry getLocationValidators() {
|
||||
return locationValidators;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<OptionParser> getOptionParsers() {
|
||||
return optionParsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an option parser to this plugin
|
||||
* @param parser The parser to add
|
||||
*/
|
||||
public void addOptionParser(OptionParser parser) {
|
||||
optionParsers.add(parser);
|
||||
if (parser instanceof SimpleOptionParser) {
|
||||
Permission parent = getServer().getPluginManager().getPermission("randomteleport.manual.option.*");
|
||||
for (String alias : ((SimpleOptionParser) parser).getAliases()) {
|
||||
Permission perm = new Permission("randomteleport.manual.option." + alias, PermissionDefault.OP);
|
||||
perm.addParent(parent, true);
|
||||
try {
|
||||
getServer().getPluginManager().addPermission(perm);
|
||||
} catch (IllegalArgumentException ignored) {} // duplicate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not a sign line matches the configured variables
|
||||
* @param line The line to match
|
||||
* @return <tt>true</tt> if it matches; <tt>false</tt> if not
|
||||
*/
|
||||
public boolean matchesSignVariable(String line) {
|
||||
return signVariables.contains(line.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and run a searcher using specified args the same way the command does
|
||||
* @param sender The sender of the command
|
||||
* @param center The center location for the searcher
|
||||
* @param args The arguments to parse
|
||||
* @return Returns the searcher that is running or null if it was stopped due to a cooldown
|
||||
* @throws IllegalArgumentException Thrown when arguments couldn't be handled properly
|
||||
*/
|
||||
public RandomSearcher parseAndRun(CommandSender sender, Location center, String[] args) {
|
||||
RandomSearcher searcher = new RandomSearcher(this, sender, center, Integer.parseInt(args[0]), Integer.parseInt(args[1]));
|
||||
|
||||
String[] optionArgs = Arrays.copyOfRange(args, 2, args.length);
|
||||
for (OptionParser parser : getOptionParsers()) {
|
||||
parser.parse(searcher, optionArgs);
|
||||
}
|
||||
|
||||
int cooldown = 0;
|
||||
|
||||
for (Entity target : searcher.getTargets()) {
|
||||
Map.Entry<Long, Integer> lastUse = cooldowns.get(searcher.getId(), target.getUniqueId());
|
||||
if (lastUse != null) {
|
||||
int targetCooldown = (int) ((System.currentTimeMillis() - lastUse.getKey()) / 1000);
|
||||
if (targetCooldown > cooldown && !target.hasPermission("randomteleport.cooldownexempt")) {
|
||||
cooldown = targetCooldown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown > 0 && cooldown < searcher.getCooldown()) {
|
||||
sendMessage(searcher.getTargets(), "error.cooldown", "cooldown_text", Integer.toString(searcher.getCooldown() - cooldown));
|
||||
return null;
|
||||
}
|
||||
sendMessage(searcher.getTargets(), "search", "worldname", searcher.getCenter().getWorld().getName());
|
||||
searcher.search().thenApply(targetLoc -> {
|
||||
searcher.getTargets().forEach(e -> {
|
||||
if (e instanceof Player) {
|
||||
Location belowLoc = targetLoc.clone().subtract(0, 1, 0);
|
||||
Block belowBlock = belowLoc.getBlock();
|
||||
((Player) e).sendBlockChange(belowLoc, belowBlock.getBlockData());
|
||||
}
|
||||
targetLoc.setX(targetLoc.getBlockX() + 0.5);
|
||||
targetLoc.setY(targetLoc.getY() + 0.1);
|
||||
targetLoc.setZ(targetLoc.getBlockZ() + 0.5);
|
||||
if (searcher.isDebug()) {
|
||||
getLogger().info("[DEBUG] Search " + searcher.getId() + " triggered by " + searcher.getInitiator().getName()
|
||||
+ " will try to teleport " + e.getType() + " " + e.getName() + "/" + e.getUniqueId() + " to " + targetLoc);
|
||||
}
|
||||
PaperLib.teleportAsync(e, targetLoc).whenComplete((success, ex) -> {
|
||||
if (success) {
|
||||
cooldowns.put(searcher.getId(), e.getUniqueId(), new AbstractMap.SimpleImmutableEntry<>(System.currentTimeMillis(), searcher.getCooldown()));
|
||||
sendMessage(e, "teleport",
|
||||
"worldname", targetLoc.getWorld().getName(),
|
||||
"x", String.valueOf(targetLoc.getBlockX()),
|
||||
"y", String.valueOf(targetLoc.getBlockY()),
|
||||
"z", String.valueOf(targetLoc.getBlockZ())
|
||||
);
|
||||
if (searcher.getOptions().containsKey("spawnpoint") && e instanceof Player) {
|
||||
if (((Player) e).getBedSpawnLocation() == null || "force".equalsIgnoreCase(searcher.getOptions().get("spawnpoint"))) {
|
||||
((Player) e).setBedSpawnLocation(targetLoc, true);
|
||||
sendMessage(e, "setspawnpoint",
|
||||
"worldname", targetLoc.getWorld().getName(),
|
||||
"x", String.valueOf(targetLoc.getBlockX()),
|
||||
"y", String.valueOf(targetLoc.getBlockY()),
|
||||
"z", String.valueOf(targetLoc.getBlockZ())
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sendMessage(e, "error.teleport",
|
||||
"worldname", targetLoc.getWorld().getName(),
|
||||
"x", String.valueOf(targetLoc.getBlockX()),
|
||||
"y", String.valueOf(targetLoc.getBlockY()),
|
||||
"z", String.valueOf(targetLoc.getBlockZ())
|
||||
);
|
||||
}
|
||||
if (ex != null && searcher.isDebug()) {
|
||||
getLogger().log(Level.SEVERE, "Error while trying to teleport to location!", ex);
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}).exceptionally(ex -> {
|
||||
sendMessage(sender, "error.location");
|
||||
if (!(ex.getCause() instanceof NotFoundException)) {
|
||||
getLogger().log(Level.SEVERE, "Error while trying to find a location!", ex);
|
||||
}
|
||||
searcher.getTargets().forEach(e -> {
|
||||
if (e != sender) {
|
||||
sendMessage(e, "error.location");
|
||||
}
|
||||
});
|
||||
return true;
|
||||
});
|
||||
return searcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a preset
|
||||
* @param sender The sender that executed the preset
|
||||
* @param preset The preset ID to run
|
||||
* @param target The player targeted by the teleporter
|
||||
* @param center The center for the search
|
||||
* @return The RandomSearcher instance that is searching
|
||||
*/
|
||||
public RandomSearcher runPreset(CommandSender sender, String preset, Player target, Location center) {
|
||||
String cmd = getConfig().getString("presets." + preset) + " -p " + target.getName();
|
||||
if (!cmd.contains("-id")) {
|
||||
cmd += " -id " + preset;
|
||||
}
|
||||
if (cmd.startsWith("/")) {
|
||||
cmd = cmd.substring(1);
|
||||
}
|
||||
if (cmd.startsWith("rtp ")) {
|
||||
cmd = cmd.substring(4);
|
||||
}
|
||||
return parseAndRun(sender, center, cmd.split(" "));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Location> getRandomLocation(Player player, Location origin, int minRange, int maxRange, LocationValidator... validators) {
|
||||
return getRandomSearcher(player, origin, minRange, maxRange, validators).search();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> teleportToRandomLocation(Player player, Location origin, int minRange, int maxRange, LocationValidator... validators) {
|
||||
return getRandomLocation(player, origin, minRange, maxRange, validators).thenApply(player::teleport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RandomSearcher getRandomSearcher(Player player, Location origin, int minRange, int maxRange, LocationValidator... validators) {
|
||||
return new RandomSearcher(this, player, origin, minRange, maxRange, validators);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the min height of a world as old versions didn't have support for this.
|
||||
* @param world The world
|
||||
* @return The min height or 0 if querying that isn't supported
|
||||
*/
|
||||
public int getMinHeight(World world) {
|
||||
if (hasMinHeight) {
|
||||
try {
|
||||
return world.getMinHeight();
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
// getMinHeight is only available starting in 1.16.5
|
||||
}
|
||||
hasMinHeight = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package de.themoep.randomteleport;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class RandomTeleportCommand implements CommandExecutor {
|
||||
private final RandomTeleport plugin;
|
||||
|
||||
public RandomTeleportCommand(RandomTeleport plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
String preset = "default";
|
||||
if (plugin.getConfig().getBoolean("use-player-world-as-preset", false)) {
|
||||
String worldName = player.getWorld().getName().toLowerCase();
|
||||
if (presetExistsInConfig(worldName))
|
||||
preset = worldName;
|
||||
}
|
||||
runPreset(preset, sender, player, player.getLocation());
|
||||
return true;
|
||||
}
|
||||
} else if (args.length == 1) {
|
||||
if ("--reload".equalsIgnoreCase(args[0]) && sender.hasPermission("randomteleport.reload")) {
|
||||
plugin.loadConfig();
|
||||
plugin.sendMessage(sender, "reloaded");
|
||||
return true;
|
||||
} else if ("--stat".equalsIgnoreCase(args[0]) && sender.hasPermission("randomteleport.stat")) {
|
||||
//TODO: teleporter and searcher statistics
|
||||
} else if (sender instanceof Player) {
|
||||
runPreset(args[0].toLowerCase(), sender, (Player) sender, ((Player) sender).getLocation());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (sender.hasPermission("randomteleport.manual")) {
|
||||
plugin.parseAndRun(sender, getLocation(sender), args);
|
||||
return true;
|
||||
} else {
|
||||
plugin.sendMessage(sender, "error.no-permission.general", "perm", "randomteleport.manual");
|
||||
return true;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (args.length == 2) {
|
||||
Player target = plugin.getServer().getPlayer(args[1]);
|
||||
if (target == null) {
|
||||
plugin.sendMessage(sender, "error.player-not-found", "what", args[1]);
|
||||
return true;
|
||||
}
|
||||
String[] presets = args[0].split(",");
|
||||
runPreset(presets[RandomTeleport.RANDOM.nextInt(presets.length)].toLowerCase(), sender, target, target.getLocation());
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void runPreset(String preset, CommandSender sender, Player target, Location center) {
|
||||
if (!sender.hasPermission("randomteleport.presets." + preset)) {
|
||||
plugin.sendMessage(sender, "error.no-permission.preset",
|
||||
"preset", preset, "perm",
|
||||
"randomteleport.presets." + preset
|
||||
);
|
||||
} else if (sender != target && !sender.hasPermission("randomteleport.tpothers")) {
|
||||
plugin.sendMessage(sender, "error.no-permission.tp-others", "perm", "randomteleport.tpothers");
|
||||
} else if (!presetExistsInConfig(preset)) {
|
||||
plugin.sendMessage(sender, "error.preset-doesnt-exist", "preset", preset);
|
||||
} else {
|
||||
if (sender == target) {
|
||||
for (RandomSearcher searcher : plugin.getRunningSearchers().values()) {
|
||||
if (searcher.getTargets().contains(target)) {
|
||||
plugin.sendMessage(sender, "error.already-searching", "preset", preset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
plugin.runPreset(plugin.getServer().getConsoleSender(), preset, target, center);
|
||||
} catch (IllegalArgumentException e) {
|
||||
plugin.sendMessage(sender, "error.preset-invalid", "preset", preset);
|
||||
plugin.getLogger().log(Level.SEVERE, "Error while parsing preset " + preset, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean presetExistsInConfig(String preset) {
|
||||
return plugin.getConfig().getString("presets." + preset) != null;
|
||||
}
|
||||
|
||||
private static Location getLocation(CommandSender sender) {
|
||||
if (sender instanceof Entity) {
|
||||
return ((Entity) sender).getLocation();
|
||||
} else if (sender instanceof BlockCommandSender) {
|
||||
return ((BlockCommandSender) sender).getBlock().getLocation();
|
||||
}
|
||||
return new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package de.themoep.randomteleport;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.validators.LocationValidator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ValidatorRegistry {
|
||||
|
||||
private Map<String, LocationValidator> validators = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Get the map of currently set location validators
|
||||
* @return The map of validators
|
||||
*/
|
||||
public Map<String, LocationValidator> getRaw() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
public Collection<LocationValidator> getAll() {
|
||||
return validators.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a location validator that is provided in this plugin
|
||||
* @param validator The validator to add
|
||||
* @return The previously registered validator of the same type and name or null if none was registered
|
||||
*/
|
||||
public LocationValidator add(LocationValidator validator) {
|
||||
return validators.put(validator.getType().toLowerCase(), validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a location validator that is provided in this plugin
|
||||
* @param validator The validator to remove
|
||||
* @return The removed registered validator with the same type or null if it wasn't registered
|
||||
*/
|
||||
public LocationValidator remove(LocationValidator validator) {
|
||||
return remove(validator.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a location validator that is provided in this plugin
|
||||
* @param type The type of the validator to remove
|
||||
* @return The removed registered validator with the same type or null if it wasn't registered
|
||||
*/
|
||||
public LocationValidator remove(String type) {
|
||||
return validators.remove(type.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a location validator that is provided in this plugin
|
||||
* @param type The type of the validator to get
|
||||
* @return The registered validator with the provided type or null if none was registered
|
||||
*/
|
||||
public LocationValidator get(String type) {
|
||||
return validators.get(type.toLowerCase());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package de.themoep.randomteleport.api;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import de.themoep.randomteleport.searcher.validators.LocationValidator;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface RandomTeleportAPI {
|
||||
|
||||
/**
|
||||
* Returns a random Location
|
||||
*
|
||||
* @param player the Player initiating the search
|
||||
* @param center the location where the search should begin
|
||||
* @param minRange the minimum distance a found location has to the center location
|
||||
* @param maxRange the maximum distance a found location has to the center location
|
||||
* @param validators additional LocationValidators to customize validity check of a location
|
||||
* @return a random CompletableFuture<Location>
|
||||
*/
|
||||
CompletableFuture<Location> getRandomLocation(Player player, Location center, int minRange, int maxRange, LocationValidator... validators);
|
||||
|
||||
/**
|
||||
* Teleports the passed Player to a random Location
|
||||
*
|
||||
* @param player the Player initiating the search
|
||||
* @param center the location where the search should begin
|
||||
* @param minRange the minimum distance a found location has to the center location
|
||||
* @param maxRange the maximum distance a found location has to the center location
|
||||
* @param validators additional LocationValidators to customize validity check of a location
|
||||
* @return a CompletableFuture<Boolean> true if teleport was successful else false
|
||||
*/
|
||||
CompletableFuture<Boolean> teleportToRandomLocation(Player player, Location center, int minRange, int maxRange, LocationValidator... validators);
|
||||
|
||||
/**
|
||||
* Creates a RandomSearcher instance with the passed parameters
|
||||
*
|
||||
* @param player the Player initiating the search
|
||||
* @param center the location where the search should begin
|
||||
* @param minRange the minimum distance a found location has to the center location
|
||||
* @param maxRange the maximum distance a found location has to the center location
|
||||
* @param validators additional LocationValidators to customize validity check of a location
|
||||
* @return a randomSearcher instance
|
||||
*/
|
||||
RandomSearcher getRandomSearcher(Player player, Location center, int minRange, int maxRange, LocationValidator... validators);
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package de.themoep.randomteleport.listeners;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.RandomTeleport;
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class SignListener implements Listener {
|
||||
|
||||
private final RandomTeleport plugin;
|
||||
|
||||
public SignListener(RandomTeleport plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignCreate(SignChangeEvent event) {
|
||||
if (plugin.matchesSignVariable(event.getLine(1))) {
|
||||
if (!event.getPlayer().hasPermission("randomteleport.sign.create")) {
|
||||
event.getBlock().breakNaturally();
|
||||
plugin.sendMessage(event.getPlayer(), "sign.no-permission.create", "perm", "randomteleport.sign.create");
|
||||
} else {
|
||||
String preset = event.getLine(2);
|
||||
if (preset != null) {
|
||||
plugin.sendMessage(event.getPlayer(), "sign.created", "preset", preset);
|
||||
if (plugin.getConfig().getString("presets." + preset.toLowerCase()) == null) {
|
||||
plugin.sendMessage(event.getPlayer(), "error.preset-doesnt-exist", "preset", preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignDestroy(BlockBreakEvent event) {
|
||||
if (event.getBlock().getType().name().contains("SIGN")) {
|
||||
Sign sign = (Sign) event.getBlock().getState();
|
||||
if (plugin.matchesSignVariable(sign.getLine(1))) {
|
||||
if (!event.getPlayer().hasPermission("randomteleport.sign.destroy")) {
|
||||
event.setCancelled(true);
|
||||
plugin.sendMessage(event.getPlayer(), "sign.no-permission.destroy", "perm", "randomteleport.sign.destroy");
|
||||
} else {
|
||||
plugin.sendMessage(event.getPlayer(), "sign.destroyed", "preset", sign.getLine(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignClick(PlayerInteractEvent event) {
|
||||
if (event.getHand() == EquipmentSlot.HAND && event.getAction() == Action.RIGHT_CLICK_BLOCK
|
||||
&& event.getClickedBlock() != null && event.getClickedBlock().getType().name().contains("SIGN")) {
|
||||
Sign sign = (Sign) event.getClickedBlock().getState();
|
||||
if (plugin.matchesSignVariable(sign.getLine(1))) {
|
||||
String preset = sign.getLine(2).toLowerCase();
|
||||
if (event.getPlayer().hasPermission("randomteleport.sign.preset." + preset)) {
|
||||
if (plugin.getConfig().getString("presets." + preset) == null) {
|
||||
plugin.sendMessage(event.getPlayer(), "error.preset-doesnt-exist", "preset", preset);
|
||||
} else {
|
||||
for (RandomSearcher searcher : plugin.getRunningSearchers().values()) {
|
||||
if (searcher.getTargets().contains(event.getPlayer())) {
|
||||
plugin.sendMessage(event.getPlayer(), "error.already-searching", "preset", preset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
plugin.runPreset(plugin.getServer().getConsoleSender(), preset, event.getPlayer(), event.getClickedBlock().getLocation());
|
||||
} catch (IllegalArgumentException e) {
|
||||
plugin.sendMessage(event.getPlayer(), "error.preset-invalid", "preset", preset);
|
||||
plugin.getLogger().log(Level.SEVERE, "Error while parsing preset " + preset, e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plugin.sendMessage(event.getPlayer(), "sign.no-permission.use",
|
||||
"preset", preset,
|
||||
"perm", "randomteleport.sign.use"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,546 @@
|
|||
package de.themoep.randomteleport.searcher;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import de.themoep.randomteleport.RandomTeleport;
|
||||
import de.themoep.randomteleport.ValidatorRegistry;
|
||||
import de.themoep.randomteleport.searcher.options.NotFoundException;
|
||||
import de.themoep.randomteleport.searcher.validators.LocationValidator;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class RandomSearcher {
|
||||
private final RandomTeleport plugin;
|
||||
private final CommandSender initiator;
|
||||
private final UUID uniqueId = UUID.randomUUID();
|
||||
|
||||
private final ValidatorRegistry validators = new ValidatorRegistry();
|
||||
|
||||
private static final List<int[]> RANDOM_LIST = new ArrayList<>();
|
||||
|
||||
static {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
RANDOM_LIST.add(new int[]{x, z});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Random random = RandomTeleport.RANDOM;
|
||||
|
||||
private Set<Entity> targets = Collections.newSetFromMap(new LinkedHashMap<>());
|
||||
|
||||
private boolean debug = false;
|
||||
private String id = null;
|
||||
private long seed = -1;
|
||||
private Location center;
|
||||
private int minRadius = 0;
|
||||
private int maxRadius = Integer.MAX_VALUE;
|
||||
private int checkDelay = 1;
|
||||
private boolean minYWasProvided = false;
|
||||
private int minY;
|
||||
private boolean maxYWasProvided = false;
|
||||
private int maxY;
|
||||
private boolean loadedOnly = false;
|
||||
private boolean generatedOnly = false;
|
||||
private int maxTries = 100;
|
||||
private int cooldown;
|
||||
private Map<String, String> options = new LinkedHashMap<>();
|
||||
|
||||
private long lastCheck;
|
||||
private int checks = 0;
|
||||
private final Multimap<Integer, Integer> checked = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
|
||||
private CompletableFuture<Location> future = null;
|
||||
|
||||
public RandomSearcher(RandomTeleport plugin, CommandSender initiator, Location center, int minRadius, int maxRadius, LocationValidator... validators) {
|
||||
this.plugin = plugin;
|
||||
this.initiator = initiator;
|
||||
setCenter(center);
|
||||
setMinRadius(minRadius);
|
||||
setMaxRadius(maxRadius);
|
||||
minY = plugin.getMinHeight(center.getWorld());
|
||||
if (center.getWorld().getEnvironment() == World.Environment.NETHER) {
|
||||
maxY = 126;
|
||||
} else {
|
||||
maxY = center.getWorld().getMaxHeight();
|
||||
}
|
||||
this.validators.getRaw().putAll(plugin.getLocationValidators().getRaw());
|
||||
Arrays.asList(validators).forEach(this.validators::add);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entities targeted by this searcher
|
||||
* @return The entitiy to target
|
||||
*/
|
||||
public Set<Entity> getTargets() {
|
||||
return targets;
|
||||
}
|
||||
|
||||
public ValidatorRegistry getValidators() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ID unique to each searcher
|
||||
* @return The searcher's version 4 UUID
|
||||
*/
|
||||
public UUID getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable debugging messages for this searcher
|
||||
* @param debug Whether to print debug messages
|
||||
*/
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if debugging is enabled for this searcher
|
||||
* @return Whether to print debug messages
|
||||
*/
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ID of this searcher used for cooldowns. Set to null to use an automatically generated one!
|
||||
* @param id The ID of the searcher
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the searcher used for cooldowns. If no specific one is set then one generated by the settings will be returned
|
||||
* @return The ID of the searcher
|
||||
*/
|
||||
public String getId() {
|
||||
if (id == null) {
|
||||
return toString();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the seed that should be used when selecting locations. See {@link Random#setSeed(long)}.
|
||||
* @param seed The seed.
|
||||
*/
|
||||
public void setSeed(long seed) {
|
||||
this.seed = seed;
|
||||
if (random == RandomTeleport.RANDOM) {
|
||||
random = new Random(seed);
|
||||
} else {
|
||||
random.setSeed(seed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the seed of this random searcher. Returns -1 if none was set.
|
||||
* @return The seed or -1
|
||||
*/
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set the Random instance used for selecting coordinates
|
||||
* @param random The random instance
|
||||
*/
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the random instance that is used for finding locations
|
||||
* @return The random instance; {@link RandomTeleport#RANDOM} by default
|
||||
*/
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the center for this searcher
|
||||
* @return The center location
|
||||
*/
|
||||
public Location getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the center of this searcher
|
||||
* @param center The center location; never null
|
||||
*/
|
||||
public void setCenter(Location center) {
|
||||
Validate.notNull(center, "Center cannot be null!");
|
||||
Validate.notNull(center.getWorld(), "Center world cannot be null!");
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum radius
|
||||
* @return The minimum radius, always positive and less than the max radius!
|
||||
*/
|
||||
public int getMinRadius() {
|
||||
return minRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum search radius
|
||||
* @param minRadius The min radius; has to be positive and less than the max radius!
|
||||
*/
|
||||
public void setMinRadius(int minRadius) {
|
||||
Validate.isTrue(minRadius >= 0 && minRadius < maxRadius, "Min radius has to be positive and less than the max radius!");
|
||||
this.minRadius = minRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum radius
|
||||
* @return The maximum radius, always greater than the minimum radius
|
||||
*/
|
||||
public int getMaxRadius() {
|
||||
return maxRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum search radius
|
||||
* @param maxRadius The max radius; has to be greater than the min radius!
|
||||
*/
|
||||
public void setMaxRadius(int maxRadius) {
|
||||
Validate.isTrue(maxRadius > minRadius, "Max radius has to be greater than the min radius!");
|
||||
this.maxRadius = maxRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the delay in ticks between checking chunks when searching
|
||||
* @return The delay in ticks
|
||||
*/
|
||||
public int getCheckDelay() {
|
||||
return checkDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the delay in ticks between checking chunks when searching
|
||||
* @param checkDelay The delay in ticks
|
||||
*/
|
||||
public void setCheckDelay(int checkDelay) {
|
||||
this.checkDelay = checkDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world this searcher will search in
|
||||
* @return The world
|
||||
*/
|
||||
public World getWorld() {
|
||||
return center.getWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the world this searcher will search in
|
||||
* @param world The world
|
||||
*/
|
||||
public void setWorld(World world) {
|
||||
center.setWorld(world);
|
||||
if (!minYWasProvided) {
|
||||
minY = plugin.getMinHeight(world);
|
||||
}
|
||||
|
||||
if (!maxYWasProvided) {
|
||||
if (world.getEnvironment() == World.Environment.NETHER) {
|
||||
maxY = 126;
|
||||
} else {
|
||||
maxY = world.getMaxHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum Y
|
||||
* @return The minimum Y, always positive and less than the max Y!
|
||||
*/
|
||||
public int getMinY() {
|
||||
return minY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum search Y
|
||||
* @param minY The min Y; has to be positive and less than the max Y!
|
||||
*/
|
||||
public void setMinY(int minY) {
|
||||
Validate.isTrue(minY >= plugin.getMinHeight(center.getWorld()), "Min Y has to be at least the world's minimum height!");
|
||||
Validate.isTrue(minY < maxY, "Min Y has to be less than the max Y!");
|
||||
this.minY = minY;
|
||||
minYWasProvided = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum Y
|
||||
* @return The maximum Y, always greater than the minimum Y
|
||||
*/
|
||||
public int getMaxY() {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum search Y
|
||||
* @param maxY The max Y; has to be greater than the min Y!
|
||||
*/
|
||||
public void setMaxY(int maxY) {
|
||||
Validate.isTrue(maxY <= center.getWorld().getMaxHeight() && maxY > minY, "Max Y has to be greater than the min Y and at most the world's max height!");
|
||||
this.maxY = maxY;
|
||||
maxYWasProvided = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default it will search for coordinates in any chunk, even unloaded ones prompting the server to load new
|
||||
* chunks which might result in some performance impact if the server doesn't support async loading. This disables
|
||||
* that and only searches in already loaded chunks. (But might fail more often)
|
||||
* @param loadedOnly Whether or not to search in loaded chunks only
|
||||
*/
|
||||
public void searchInLoadedOnly(boolean loadedOnly) {
|
||||
this.loadedOnly = loadedOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default it will search for coordinates in any chunk, even ungenerated ones prompting the world to get
|
||||
* generated at the point which might result in some performance impact. This disables that and only searches
|
||||
* in already generated chunks.
|
||||
* @param generatedOnly Whether or not to search in generated chunks only
|
||||
*/
|
||||
public void searchInGeneratedOnly(boolean generatedOnly) {
|
||||
this.generatedOnly = generatedOnly;
|
||||
}
|
||||
|
||||
public int getMaxTries() {
|
||||
return maxTries;
|
||||
}
|
||||
|
||||
public void setMaxTries(int maxTries) {
|
||||
this.maxTries = maxTries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown that a player has to wait before using a searcher with similar settings again
|
||||
* @param cooldown The cooldown in seconds
|
||||
*/
|
||||
public void setCooldown(int cooldown) {
|
||||
Validate.isTrue(cooldown >= 0, "Cooldown can't be negative!");
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cooldown that a player has to wait before using a searcher with similar settings again
|
||||
* @return The cooldown in seconds
|
||||
*/
|
||||
public int getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get additional options
|
||||
* @return A map of additional options
|
||||
*/
|
||||
public Map<String, String> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a valid location
|
||||
* @return A CompletableFuture for when the search task is complete
|
||||
* @throws IllegalStateException when the searcher is already running
|
||||
*/
|
||||
public CompletableFuture<Location> search() {
|
||||
if (plugin.getRunningSearchers().containsKey(uniqueId)) {
|
||||
throw new IllegalStateException("Searcher " + uniqueId + " is already running!");
|
||||
}
|
||||
plugin.getRunningSearchers().put(uniqueId, this);
|
||||
if (targets.isEmpty() && initiator instanceof Entity) {
|
||||
targets.add((Entity) initiator);
|
||||
}
|
||||
future = new CompletableFuture<>();
|
||||
checks = 0;
|
||||
checked.clear();
|
||||
if (debug) {
|
||||
plugin.getLogger().info("[DEBUG] " + uniqueId + " " + this + " started searching...");
|
||||
}
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> checkRandom(future));
|
||||
future.whenComplete((l, e) -> plugin.getRunningSearchers().remove(uniqueId));
|
||||
return future;
|
||||
}
|
||||
|
||||
private void checkRandom(CompletableFuture<Location> future) {
|
||||
if (checks >= maxTries) {
|
||||
future.completeExceptionally(new NotFoundException("location"));
|
||||
return;
|
||||
}
|
||||
if (future.isCancelled() || future.isDone() || future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
lastCheck = center.getWorld().getTime();
|
||||
Location randomLoc = center.clone();
|
||||
randomLoc.setY(plugin.getMinHeight(center.getWorld()));
|
||||
int minChunk = minRadius >> 4;
|
||||
int maxChunk = maxRadius >> 4;
|
||||
int randChunkX;
|
||||
int randChunkZ;
|
||||
Chunk[] loadedChunks = new Chunk[0];
|
||||
if (loadedOnly) {
|
||||
loadedChunks = randomLoc.getWorld().getLoadedChunks();
|
||||
if (loadedChunks.length == 0) {
|
||||
future.completeExceptionally(new NotFoundException("loaded chunk"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
checks++;
|
||||
if (checks >= maxTries) {
|
||||
future.completeExceptionally(new NotFoundException("location"));
|
||||
return;
|
||||
}
|
||||
if (loadedOnly) {
|
||||
Chunk chunk = loadedChunks[random.nextInt(loadedChunks.length)];
|
||||
randChunkX = chunk.getX();
|
||||
randChunkZ = chunk.getZ();
|
||||
} else {
|
||||
randChunkX = (random.nextBoolean() ? 1 : -1) * random.nextInt(maxChunk + 1);
|
||||
randChunkZ = (random.nextBoolean() ? 1 : -1) * random.nextInt(maxChunk + 1);
|
||||
}
|
||||
} while (!checked.put(randChunkX, randChunkZ)
|
||||
|| !inRadius(Math.abs(randChunkX), Math.abs(randChunkZ), minChunk, maxChunk)
|
||||
|| (generatedOnly && !PaperLib.isChunkGenerated(randomLoc.getWorld(), randChunkX, randChunkZ)));
|
||||
|
||||
randomLoc.setX(((center.getBlockX() >> 4) + randChunkX) * 16);
|
||||
randomLoc.setZ(((center.getBlockZ() >> 4) + randChunkZ) * 16);
|
||||
PaperLib.getChunkAtAsync(randomLoc).thenApply(c -> {
|
||||
checks++;
|
||||
if (c == null) {
|
||||
// Chunk not generated, test another one
|
||||
checkRandom(future);
|
||||
return false;
|
||||
}
|
||||
c.addPluginChunkTicket(plugin);
|
||||
try {
|
||||
int indexOffset = random.nextInt(RANDOM_LIST.size());
|
||||
Location foundLoc = null;
|
||||
for (int i = 0; i < RANDOM_LIST.size(); i++) {
|
||||
int index = (i + indexOffset) % RANDOM_LIST.size();
|
||||
boolean validated = true;
|
||||
Location loc = randomLoc.clone().add(RANDOM_LIST.get(index)[0], 0, RANDOM_LIST.get(index)[1]);
|
||||
|
||||
if (!inRadius(loc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (LocationValidator validator : getValidators().getAll()) {
|
||||
if (!validator.validate(this, loc)) {
|
||||
validated = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (validated) {
|
||||
foundLoc = loc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundLoc != null) {
|
||||
// all checks are for the top block, put we want a location above that so add 1 to y
|
||||
future.complete(foundLoc.add(0, 1, 0));
|
||||
return true;
|
||||
}
|
||||
long diff = center.getWorld().getTime() - lastCheck;
|
||||
if (diff < checkDelay) {
|
||||
plugin.getServer().getScheduler().runTaskLater(plugin, () -> checkRandom(future), checkDelay - diff);
|
||||
} else {
|
||||
checkRandom(future);
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
c.removePluginChunkTicket(plugin);
|
||||
}
|
||||
}).exceptionally(future::completeExceptionally);
|
||||
}
|
||||
|
||||
private boolean inRadius(Location location) {
|
||||
int diffX = Math.abs(location.getBlockX() - center.getBlockX());
|
||||
int diffZ = Math.abs(location.getBlockZ() - center.getBlockZ());
|
||||
return inRadius(diffX, diffZ, minRadius, maxRadius);
|
||||
}
|
||||
|
||||
private boolean inRadius(int diffX, int diffZ, int minRadius, int maxRadius) {
|
||||
return diffX >= minRadius && diffX <= maxRadius && diffZ <= maxRadius
|
||||
|| diffZ >= minRadius && diffZ <= maxRadius && diffX <= maxRadius;
|
||||
}
|
||||
|
||||
public RandomTeleport getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sender who initiated this search
|
||||
* @return The initiator
|
||||
*/
|
||||
public CommandSender getInitiator() {
|
||||
return initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently running search future
|
||||
* @return The currently running search future or null if none is running
|
||||
*/
|
||||
public CompletableFuture<Location> getFuture() {
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RandomSearcher{" +
|
||||
"id='" + id + '\'' +
|
||||
", seed=" + seed +
|
||||
", center=" + center +
|
||||
", minRadius=" + minRadius +
|
||||
", maxRadius=" + maxRadius +
|
||||
", loadedOnly=" + loadedOnly +
|
||||
", generatedOnly=" + generatedOnly +
|
||||
", maxTries=" + maxTries +
|
||||
", cooldown=" + cooldown +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
public class AdditionalOptionParser extends SimpleOptionParser {
|
||||
public AdditionalOptionParser(String... optionAliases) {
|
||||
super(optionAliases, ((searcher, args) -> {
|
||||
searcher.getOptions().put(optionAliases[0], args.length > 0 ? String.join(" ", args) : "true");
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2022 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BooleanOptionParser extends SimpleOptionParser {
|
||||
|
||||
public BooleanOptionParser(String optionAlias, Consumer<RandomSearcher> consumer) {
|
||||
this(new String[]{optionAlias}, consumer);
|
||||
}
|
||||
|
||||
public BooleanOptionParser(String[] optionAliases, Consumer<RandomSearcher> consumer) {
|
||||
super(optionAliases, 0, ((searcher, args) -> {
|
||||
consumer.accept(searcher);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
public class NotFoundException extends IllegalArgumentException {
|
||||
private final String what;
|
||||
|
||||
public NotFoundException(String what) {
|
||||
super(what + " was not found!");
|
||||
this.what = what;
|
||||
}
|
||||
|
||||
public String getWhat() {
|
||||
return what;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
|
||||
public interface OptionParser {
|
||||
|
||||
boolean parse(RandomSearcher searcher, String[] args);
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
public class PlayerNotFoundException extends NotFoundException {
|
||||
|
||||
public PlayerNotFoundException(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SimpleOptionParser implements OptionParser {
|
||||
|
||||
private Set<String> aliases;
|
||||
private final int argsLength;
|
||||
private final BiFunction<RandomSearcher, String[], Boolean> parser;
|
||||
|
||||
public SimpleOptionParser(String option, BiFunction<RandomSearcher, String[], Boolean> parser) {
|
||||
this(new String[]{option}, parser);
|
||||
}
|
||||
|
||||
public SimpleOptionParser(String[] optionAliases, BiFunction<RandomSearcher, String[], Boolean> parser) {
|
||||
this(optionAliases, -1, parser);
|
||||
}
|
||||
|
||||
public SimpleOptionParser(String[] optionAliases, int argsLength, BiFunction<RandomSearcher, String[], Boolean> parser) {
|
||||
Validate.notEmpty(optionAliases);
|
||||
this.aliases = Arrays.stream(optionAliases).map(String::toLowerCase).collect(Collectors.toSet());
|
||||
this.argsLength = argsLength;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(RandomSearcher searcher, String[] args) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].startsWith("-")) {
|
||||
String option = args[i].toLowerCase().substring(1);
|
||||
if (option.startsWith("-")) {
|
||||
option = args[i].substring(1);
|
||||
}
|
||||
if (aliases.contains(option)) {
|
||||
if (!hasAccess(searcher.getInitiator())) {
|
||||
throw new IllegalArgumentException(searcher.getPlugin().getTextMessage(
|
||||
searcher.getInitiator(), "error.no-permission.option",
|
||||
"option", option,
|
||||
"perm", "randomteleport.manual.option." + aliases.iterator().next()));
|
||||
}
|
||||
i++;
|
||||
int argLength = argsLength > 0 ? argsLength : 0;
|
||||
for (int j = i + argLength; j < args.length; j++) {
|
||||
if (!args[j].startsWith("-")) {
|
||||
argLength++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + argLength <= args.length) {
|
||||
return parser.apply(searcher, Arrays.copyOfRange(args, i, i + argLength));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasAccess(CommandSender initiator) {
|
||||
for (String alias : aliases) {
|
||||
if (initiator.hasPermission("randomteleport.manual.option." + alias)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<String> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package de.themoep.randomteleport.searcher.options;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
public class WorldNotFoundException extends NotFoundException {
|
||||
|
||||
public WorldNotFoundException(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BiomeValidator extends LocationValidator {
|
||||
|
||||
private final boolean whitelist;
|
||||
private final Set<Biome> biomes = EnumSet.noneOf(Biome.class);
|
||||
|
||||
public BiomeValidator(Biome... biomes) {
|
||||
this(true, biomes);
|
||||
}
|
||||
|
||||
public BiomeValidator(boolean whitelist, Biome... biomes) {
|
||||
super("biome");
|
||||
this.whitelist = whitelist;
|
||||
Collections.addAll(this.biomes, biomes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(RandomSearcher searcher, Location location) {
|
||||
Block block = location.getBlock();
|
||||
return block != null && biomes.contains(block.getBiome()) == whitelist;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockValidator extends LocationValidator {
|
||||
|
||||
private final boolean whitelist;
|
||||
private final Set<Material> materials = EnumSet.noneOf(Material.class);
|
||||
|
||||
public BlockValidator(Material... materials) {
|
||||
this(true, materials);
|
||||
}
|
||||
|
||||
public BlockValidator(boolean whitelist, Material... materials) {
|
||||
super("block");
|
||||
this.whitelist = whitelist;
|
||||
Collections.addAll(this.materials, materials);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(RandomSearcher searcher, Location location) {
|
||||
Block block = location.getBlock();
|
||||
return block != null && materials.contains(block.getType()) == whitelist;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class HeightValidator extends LocationValidator {
|
||||
|
||||
private final EnumSet<Material> unsafeBlocks;
|
||||
|
||||
public HeightValidator(Material[] unsafeBlocks) {
|
||||
super("height");
|
||||
this.unsafeBlocks = EnumSet.noneOf(Material.class);
|
||||
Collections.addAll(this.unsafeBlocks, unsafeBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(RandomSearcher searcher, Location location) {
|
||||
Block block = location.getWorld().getHighestBlockAt(location);
|
||||
if (block.getY() > searcher.getMaxY()) {
|
||||
block = location.getWorld().getBlockAt(
|
||||
block.getX(),
|
||||
searcher.getMinY() + searcher.getRandom().nextInt(searcher.getMaxY() - searcher.getMinY()),
|
||||
block.getZ()
|
||||
);
|
||||
}
|
||||
while (block.isEmpty()) {
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
if (block == null || block.getY() < searcher.getMinY()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
location.setY(block.getY());
|
||||
return isSafe(block.getRelative(BlockFace.UP)) && isSafe(block.getRelative(BlockFace.UP, 2));
|
||||
}
|
||||
|
||||
private boolean isSafe(Block block) {
|
||||
return block.isPassable() && !block.isLiquid() && !unsafeBlocks.contains(block.getType());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public abstract class LocationValidator {
|
||||
private String type;
|
||||
|
||||
public LocationValidator(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a location
|
||||
* @param searcher The searcher attempting to use this validator
|
||||
* @param location The location to validate
|
||||
* @return True if it's valid; false if not
|
||||
*/
|
||||
public abstract boolean validate(RandomSearcher searcher, Location location);
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ProtectionValidator extends LocationValidator {
|
||||
|
||||
public ProtectionValidator() {
|
||||
super("protection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(RandomSearcher searcher, Location location) {
|
||||
if (searcher.getTargets().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (Entity entity : searcher.getTargets()) {
|
||||
if (entity instanceof Player && !searcher.getPlugin().getHookManager().canBuild((Player) entity, location)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package de.themoep.randomteleport.searcher.validators;
|
||||
|
||||
/*
|
||||
* RandomTeleport - randomteleport-plugin - $project.description
|
||||
* Copyright (c) 2019 Max Lee aka Phoenix616 (mail@moep.tv)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import de.themoep.randomteleport.searcher.RandomSearcher;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class WorldborderValidator extends LocationValidator {
|
||||
|
||||
public WorldborderValidator() {
|
||||
super("worldborder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(RandomSearcher searcher, Location location) {
|
||||
return searcher.getPlugin().getHookManager().isInsideBorder(location);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
# Default language to use when client's language isn't available
|
||||
lang: en
|
||||
# Some debug information
|
||||
debug: true
|
||||
# Delay in ticks between checking chunks when searching
|
||||
|
||||
# Should we search for a preset named like the world the player is in when using /rtp without parameters?
|
||||
use-player-world-as-preset: false
|
||||
|
||||
# Blocks to teleport on in normal mode
|
||||
safe-blocks:
|
||||
- sand
|
||||
- sandstone
|
||||
- gravel
|
||||
- dirt
|
||||
- grass_block
|
||||
- coarse_dirt
|
||||
- podzol
|
||||
- stone
|
||||
- granite
|
||||
- diorite
|
||||
- andesite
|
||||
- cobblestone
|
||||
- end_stone
|
||||
- netherrack
|
||||
|
||||
# Blocks not to teleport on or into
|
||||
unsafe-blocks:
|
||||
- water
|
||||
- lava
|
||||
- oak_sapling
|
||||
- spruce_sapling
|
||||
- birch_sapling
|
||||
- jungle_sapling
|
||||
- acacia_sapling
|
||||
- dark_oak_sapling
|
||||
- white_bed
|
||||
- orange_bed
|
||||
- magenta_bed
|
||||
- light_blue_bed
|
||||
- yellow_bed
|
||||
- lime_bed
|
||||
- pink_bed
|
||||
- gray_bed
|
||||
- light_gray_bed
|
||||
- cyan_bed
|
||||
- purple_bed
|
||||
- blue_bed
|
||||
- brown_bed
|
||||
- green_bed
|
||||
- red_bed
|
||||
- black_bed
|
||||
- powered_rail
|
||||
- detector_rail
|
||||
- cobweb
|
||||
- piston_head
|
||||
- tnt
|
||||
- torch
|
||||
- fire
|
||||
- sign
|
||||
- ladder
|
||||
- rail
|
||||
- wall_sign
|
||||
- lever
|
||||
- stone_pressure_plate
|
||||
- iron_door
|
||||
- redstone_wall_torch
|
||||
- redstone_torch
|
||||
- stone_button
|
||||
- cactus
|
||||
- magma_block
|
||||
- nether_portal
|
||||
- vine
|
||||
- end_portal
|
||||
- end_portal_frame
|
||||
- tripwire_hook
|
||||
- tripwire
|
||||
- flower_pot
|
||||
- oak_leaves
|
||||
- spruce_leaves
|
||||
- birch_leaves
|
||||
- jungle_leaves
|
||||
- acacia_leaves
|
||||
- dark_oak_leaves
|
||||
- barrier
|
||||
- iron_trapdoor
|
||||
- oak_trapdoor
|
||||
- spruce_trapdoor
|
||||
- birch_trapdoor
|
||||
- jungle_trapdoor
|
||||
- acacia_trapdoor
|
||||
- dark_oak_trapdoor
|
||||
- oak_door
|
||||
- spruce_door
|
||||
- birch_door
|
||||
- jungle_door
|
||||
- acacia_door
|
||||
- dark_oak_door
|
||||
- end_rod
|
||||
- end_gateway
|
||||
- powder_snow
|
||||
|
||||
sign-variables:
|
||||
- "[RTP]"
|
||||
- "[RandomTP]"
|
||||
|
||||
# Just write your command arguments as you would use it ingame behind /rtp
|
||||
# Don't use the -p parameter, this will get added automatically with the senders name/the specified playername
|
||||
presets:
|
||||
# Triggered when you use /rtp without any additional paramters
|
||||
default: "100 1000"
|
||||
# add more to use /rtp <rtpname>, player needs "randomteleport.presets.<rtpname>"
|
||||
# <rtpname>: "/rtp 1 2"
|
||||
test: "10 200 -f"
|
|
@ -0,0 +1,27 @@
|
|||
reloaded: "&eReloaded the config. Some settings might require a server restart!"
|
||||
search: "&7RandomTeleport searches for a safe place in world {worldname}. . ."
|
||||
teleport: "&7RandomTeleport teleported you to X: {x} Y: {y} Z: {z}!"
|
||||
setspawnpoint: "&7Your Respawnpoint has been set to your current location!"
|
||||
sign:
|
||||
created: "&aRandomTeleport preset sign &e{preset}&a created!"
|
||||
destroyed: "&aRandomTeleport preset sign &e{preset}&a destroyed!"
|
||||
no-permission:
|
||||
destroy: "&cYou don't have permission to destroy RandomTeleport preset signs! &o({perm})"
|
||||
create: "&cYou don't have permission to create RandomTeleport preset signs! &o({perm})"
|
||||
use: "&cYou don't have permission to use the preset &6{preset}&c! &o({perm})"
|
||||
error:
|
||||
location: "&4Error: &cRandomTeleport could not find a safe location!"
|
||||
teleport: "&4Error: &cRandomTeleport could not teleport you to X: {x} Y: {y} Z: {z}!"
|
||||
cooldown: "&cYou have to wait {cooldown_text}s before using this RandomTeleport again!"
|
||||
parse-error: "&cError while parsing option &f{option}&c with value &f{value}&c: {error}"
|
||||
not-found: "&cCould not find &f{what}&c!"
|
||||
player-not-found: "&cCould not find a player with the name &f{what}&c!"
|
||||
world-not-found: "&cCould not find a world with the name &f{what}&c!"
|
||||
preset-doesnt-exist: "&cThe RandomTeleport preset &6{preset}&c does not exist!"
|
||||
preset-invalid: "&cThe preset &6{preset}&c is not setup correctly! Please contact an admin."
|
||||
already-searching: "&cA search is already in progress&c!"
|
||||
no-permission:
|
||||
general: "&cYou don't have permission to do that! &o({perm})"
|
||||
option: "&cYou don't have permission to use the option {option}! &o({perm})"
|
||||
preset: "&cYou don't have permission to use the preset &6{preset}&c! &o({perm})"
|
||||
tp-others: "&cYou don't have permission to teleport other players! &o({perm})"
|
|
@ -0,0 +1,78 @@
|
|||
name: RandomTeleport
|
||||
provides: [FUBSRandomTeleport]
|
||||
main: de.themoep.randomteleport.RandomTeleport
|
||||
version: '${minecraft.plugin.version}'
|
||||
api-version: 1.13
|
||||
description: ${project.description}
|
||||
author: Phoenix616
|
||||
website: https://github.com/Phoenix616/RandomTeleport/
|
||||
softdepend: [WorldGuard, Factions, GriefPrevention, RedProtect, WorldBorder]
|
||||
commands:
|
||||
randomteleport:
|
||||
aliases: [randomtp, rtp]
|
||||
description: RandomTeleport command.
|
||||
permission: randomteleport.use
|
||||
usage: |
|
||||
/<command> - uses the default preset
|
||||
/<command> <preset1,...> [<playername>] - uses a specific or random preset
|
||||
/<command> <minRange> <maxRange> [-p, -w, -x, -z, -c, -f]
|
||||
minRange - minimum distance to the center point (square shaped)
|
||||
maxRange - maximum distance to the center point (square shaped)
|
||||
Options:
|
||||
> -p,-player <playername> - teleports other players
|
||||
> -w,-world <world1,...> - teleports the player in a specific or random world
|
||||
> -b,-biome <biomename> [<biome 2> ...] - only teleport to this biome (multiple allowed, Bukkit biome names!)
|
||||
> -x,-xPos <x value> - x axis of the center point, if not set the player's x axis is used
|
||||
> -z,-zPos <z value> - z axis of the center point, if not set the player's z axis is used
|
||||
> -minY <y value> - minimum y value that the random location should have (default: 0)
|
||||
> -maxY <y value> - maximum y value that the random location should have (default: world height, half in nether)
|
||||
> -l,-loaded - only search loaded chunks for possible locations (might fail more often)
|
||||
> -g,-generated - only search generated chunks for possible locations
|
||||
> -c, -cooldown <seconds> - cooldown in seconds after which the player can use this teleporter again
|
||||
> -id <id> - The ID to use for the cooldown, uses automatically generated one if not provided
|
||||
> -f,-force - teleport even if there is no dirt/grass/sand/gravel, only checks for lava/water/cactus, ignores WorldGuard/Faction regions
|
||||
> -f,-force [<blocks|regions>] - only ignore blocks or regions
|
||||
> -t,-tries <amount> - the amount of times the plugin should try to find a random location before giving up
|
||||
> -sp,spawnpoint [force] - set the respawn point of the player to the location he teleported to (force overrides existing spawnpoint)
|
||||
/<command> --stat - shows a statistic of the teleports since the last restart
|
||||
/<command> --reload - reloads the config
|
||||
permissions:
|
||||
randomteleport.use:
|
||||
description: Gives permission to the command
|
||||
default: op
|
||||
randomteleport.manual:
|
||||
description: Gives permission to manually specify parameters in the command
|
||||
default: op
|
||||
randomteleport.manual.option.*:
|
||||
description: Gives permission to use certain options in the command
|
||||
default: op
|
||||
randomteleport.tpothers:
|
||||
description: Gives permission to teleport other players
|
||||
default: op
|
||||
randomteleport.cooldownexempt:
|
||||
description: Teleportcooldown does not effect these players
|
||||
default: op
|
||||
randomteleport.stat:
|
||||
description: Permission for showing the teleport statistic
|
||||
default: op
|
||||
randomteleport.reload:
|
||||
description: Permission to use the reload command
|
||||
default: op
|
||||
randomteleport.presets.default:
|
||||
description: Gives permission to use the default random teleport preset
|
||||
default: op
|
||||
randomteleport.presets.*:
|
||||
description: Gives permission to use all random teleport presets
|
||||
default: op
|
||||
randomteleport.sign.preset.default:
|
||||
description: Gives permission to use the default preset with a rightclick on a preset sign
|
||||
default: op
|
||||
randomteleport.sign.preset.*:
|
||||
description: Gives permission to use all presets with a rightclick on a preset sign
|
||||
default: op
|
||||
randomteleport.sign.create:
|
||||
description: Allows creating preset signs ([rtp] or [RandomTP] on the 2nd line and the preset name on the 3rd)
|
||||
default: op
|
||||
randomteleport.sign.destroy:
|
||||
description: Allows destroying preset signs ([rtp] or [RandomTP] on the 2nd line and the preset name on the 3rd)
|
||||
default: op
|
Loading…
Reference in New Issue