mirror of
https://github.com/md5sha256/AreaShop.git
synced 2026-11-06 17:32:43 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6d1f3389c | ||
|
|
834ea5d994 | ||
|
|
f89d917b08 | ||
|
|
c2b12119e8 | ||
|
|
8c3b2fe8cc | ||
|
|
2a18ec75b0 |
No files matched your search
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a problem in the plugin
|
||||
title: ''
|
||||
labels: 'NEW, Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Current behavior**
|
||||
<!--- Tell what happens currently and/or show the stacktrace if an error occured -->
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
<!--- Tell what you expected to happen instead -->
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
<!--- Exactly show how this bug can be triggered -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
|
||||
**Your environment**
|
||||
<!--- Indicate which versions you use -->
|
||||
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
|
||||
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
|
||||
* Server platform (Bukkit, Spigot, etc.):
|
||||
* Server version:
|
||||
* AreaShop version:
|
||||
* WorldEdit version:
|
||||
* WorldGuard version:
|
||||
* Vault version:
|
||||
|
||||
|
||||
**Your config files**
|
||||
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea
|
||||
title: ''
|
||||
labels: 'NEW, Type: Feature'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the problem you are trying to solve with this feature request**
|
||||
<!-- When I know the problem you are trying to solve I can help you to think about the best solution -->
|
||||
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!-- Describe the config settings, commands and other features that should be added -->
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Support question
|
||||
about: Ask help with the setup or usage of the plugin
|
||||
title: ''
|
||||
labels: 'NEW, Type: Support'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Current behavior**
|
||||
<!--- Tell what happens currently -->
|
||||
|
||||
|
||||
**Desired behavior**
|
||||
<!--- Tell what you want to happen instead -->
|
||||
|
||||
|
||||
**Your environment**
|
||||
<!--- Indicate which versions you use -->
|
||||
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
|
||||
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
|
||||
* Server platform (Bukkit, Spigot, etc.):
|
||||
* Server version:
|
||||
* AreaShop version:
|
||||
* WorldEdit version:
|
||||
* WorldGuard version:
|
||||
* Vault version:
|
||||
|
||||
|
||||
**Your config files**
|
||||
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
|
||||
@@ -0,0 +1,32 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
|
||||
+4
-12
@@ -1,7 +1,6 @@
|
||||
# Maven stuff
|
||||
/target
|
||||
target
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
@@ -15,19 +14,12 @@ local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# IntelliJ IDEA
|
||||
*.iml
|
||||
.idea
|
||||
dependency-reduced-pom.xml
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
desktop.ini
|
||||
@@ -1 +0,0 @@
|
||||
/target
|
||||
+300
-230
@@ -1,230 +1,300 @@
|
||||
<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>
|
||||
<artifactId>areashop</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>AreaShop</name>
|
||||
<version>2.3.2</version> <!-- Main plugin version -->
|
||||
|
||||
<parent>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-parent</artifactId>
|
||||
<version>parent</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.7.9-R0.2</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldguard-5</artifactId>
|
||||
<version>WorldGuard-5</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldguard-6</artifactId>
|
||||
<version>WorldGuard-6</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldguard-6_1_3</artifactId>
|
||||
<version>WorldGuard-6_1_3</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>AreaShopInterface</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldedit-5</artifactId>
|
||||
<version>WorldEdit-5</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldedit-6</artifactId>
|
||||
<version>WorldEdit-6</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldedit</artifactId>
|
||||
<version>6.0.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldguard</artifactId>
|
||||
<version>6.0.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<!-- Copy the jar file to a test server, activate by using -DcopyResult="/path/to/test/server" -->
|
||||
<profile>
|
||||
<id>test-locally</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>copyResult</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy file="./target/${project.build.finalName}.jar" tofile="${copyResult}\${project.build.finalName}.jar"/>
|
||||
</target>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Package the source files in a jar, activate by using -Dsources -->
|
||||
<profile>
|
||||
<id>package-sources</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>sources</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Produce javadoc files, activate by using -Djavadoc -->
|
||||
<profile>
|
||||
<id>generate-javadoc</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>javadoc</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<excludePackageNames>me.wiefferink.areashop.lib</excludePackageNames>
|
||||
<destDir>${javadoc}</destDir>
|
||||
<links>
|
||||
<link>https://hub.spigotmc.org/javadocs/bukkit/</link>
|
||||
<link>http://docs.sk89q.com/worldedit/apidocs/</link>
|
||||
<link>http://docs.sk89q.com/worldguard/apidocs/</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<directory>target</directory>
|
||||
<finalName>AreaShop</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
<include>config.yml</include>
|
||||
<include>hiddenConfig.yml</include>
|
||||
<include>default.yml</include>
|
||||
<include>README.md</include>
|
||||
<include>lang/*.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<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>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-parent</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>areashop</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>AreaShop</name>
|
||||
<version>2.7.1-SNAPSHOT</version> <!-- Main plugin version -->
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>aikar</id>
|
||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Bukkit, AreaShop aims to support 1.13.2+ -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.13.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- InteractiveMessenger library -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>interactivemessenger</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TaskChain library -->
|
||||
<dependency>
|
||||
<groupId>co.aikar</groupId>
|
||||
<artifactId>taskchain-bukkit</artifactId>
|
||||
<version>3.7.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JetBrains Annotations -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>19.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Paper Lib -->
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- WorldEdit/WorldGuard -->
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Interfaces that specific WorldGuard and WorldEdit versions are built against -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- WorldGuard implementations -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldguard-7</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- WorldEdit implementations -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldedit-7</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- FAWE compat -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-fawe-1-15</artifactId>
|
||||
<version>latest</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Vault -->
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- bStats -->
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.6</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<!-- Copy the jar file to a test server, activate by using -DcopyResult="/path/to/test/server" -->
|
||||
<profile>
|
||||
<id>test-locally</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>copyResult</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy file="./target/${project.build.finalName}.jar"
|
||||
tofile="${copyResult}\${project.build.finalName}.jar"/>
|
||||
</target>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Package the source files in a jar, activate by using -Dsources -->
|
||||
<profile>
|
||||
<id>package-sources</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>sources</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Produce javadoc files, activate by using -Djavadoc -->
|
||||
<profile>
|
||||
<id>generate-javadoc</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>javadoc</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<excludePackageNames>me.wiefferink.areashop.lib</excludePackageNames>
|
||||
<destDir>${javadoc}</destDir>
|
||||
<links>
|
||||
<link>https://hub.spigotmc.org/javadocs/bukkit/</link>
|
||||
<link>http://docs.sk89q.com/worldedit/apidocs/</link>
|
||||
<link>http://docs.sk89q.com/worldguard/apidocs/</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<directory>target</directory>
|
||||
<finalName>AreaShop</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
<include>config.yml</include>
|
||||
<include>hiddenConfig.yml</include>
|
||||
<include>default.yml</include>
|
||||
<include>README.md</include>
|
||||
<include>lang/*.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<!-- Relocate TaskChain -->
|
||||
<relocation>
|
||||
<pattern>co.aikar.taskchain</pattern>
|
||||
<shadedPattern>me.wiefferink.areashop.shaded.taskchain</shadedPattern>
|
||||
</relocation>
|
||||
<!-- Relocate messaging framework -->
|
||||
<relocation>
|
||||
<pattern>me.wiefferink.interactivemessenger</pattern>
|
||||
<shadedPattern>me.wiefferink.areashop.shaded.interactivemessenger</shadedPattern>
|
||||
</relocation>
|
||||
<!-- Relocate bstats -->
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>me.wiefferink.areashop.shaded.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<!-- Relocate PaperLib -->
|
||||
<relocation>
|
||||
<pattern>io.papermc</pattern>
|
||||
<shadedPattern>me.wiefferink.areashop.shaded.paperlib</shadedPattern>
|
||||
</relocation>
|
||||
<!-- Relocate Google Guice & Guice-Assisted-Inject -->
|
||||
<relocation>
|
||||
<pattern>com.google.inject</pattern>
|
||||
<shadedPattern>me.wiefferink.areashop.shaded.inject</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,746 +0,0 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
|
||||
public class Utils {
|
||||
|
||||
// Not used
|
||||
private Utils() {}
|
||||
|
||||
private static YamlConfiguration config;
|
||||
private static ArrayList<String> identifiers;
|
||||
private static ArrayList<String> seconds;
|
||||
private static ArrayList<String> minutes;
|
||||
private static ArrayList<String> hours;
|
||||
private static ArrayList<String> days;
|
||||
private static ArrayList<String> weeks;
|
||||
private static ArrayList<String> months;
|
||||
private static ArrayList<String> years;
|
||||
|
||||
public static void initialize(YamlConfiguration pluginConfig) {
|
||||
config = pluginConfig;
|
||||
|
||||
// Setup individual identifiers
|
||||
seconds = new ArrayList<>(config.getStringList("seconds"));
|
||||
minutes = new ArrayList<>(config.getStringList("minutes"));
|
||||
hours = new ArrayList<>(config.getStringList("hours"));
|
||||
days = new ArrayList<>(config.getStringList("days"));
|
||||
weeks = new ArrayList<>(config.getStringList("weeks"));
|
||||
months = new ArrayList<>(config.getStringList("months"));
|
||||
years = new ArrayList<>(config.getStringList("years"));
|
||||
// Setup all time identifiers
|
||||
identifiers = new ArrayList<>();
|
||||
identifiers.addAll(seconds);
|
||||
identifiers.addAll(minutes);
|
||||
identifiers.addAll(hours);
|
||||
identifiers.addAll(days);
|
||||
identifiers.addAll(weeks);
|
||||
identifiers.addAll(months);
|
||||
identifiers.addAll(years);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a message with a list of parts
|
||||
* @param replacements The parts to use
|
||||
* @param messagePart The message to use for the parts
|
||||
* @return A Message object containing the parts combined into one message
|
||||
*/
|
||||
public static Message combinedMessage(Collection<?> replacements, String messagePart) {
|
||||
return combinedMessage(replacements, messagePart, ", ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a message with a list of parts
|
||||
* @param replacements The parts to use
|
||||
* @param messagePart The message to use for the parts
|
||||
* @param combiner The string to use as combiner
|
||||
* @return A Message object containing the parts combined into one message
|
||||
*/
|
||||
public static Message combinedMessage(Collection<?> replacements, String messagePart, String combiner) {
|
||||
Message result = Message.none();
|
||||
boolean first = true;
|
||||
for(Object part : replacements) {
|
||||
if(first) {
|
||||
first = false;
|
||||
} else {
|
||||
result.append(combiner);
|
||||
}
|
||||
result.append(Message.fromKey(messagePart).replacements(part));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the online players
|
||||
* Provides backwards compatibility for 1.7- where it returns an array
|
||||
* @return Online players
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Collection<? extends Player> getOnlinePlayers() {
|
||||
try {
|
||||
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
|
||||
if(onlinePlayerMethod.getReturnType().equals(Collection.class)) {
|
||||
return ((Collection<? extends Player>)onlinePlayerMethod.invoke(Bukkit.getServer()));
|
||||
} else {
|
||||
return Arrays.asList((Player[])onlinePlayerMethod.invoke(Bukkit.getServer()));
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
AreaShop.debug("getOnlinePlayers error: "+ex.getMessage());
|
||||
}
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a map from a location, to save it in the config
|
||||
* @param location The location to transform
|
||||
* @param setPitchYaw true to save the pitch and yaw, otherwise false
|
||||
* @return The map with the location values
|
||||
*/
|
||||
public static ConfigurationSection locationToConfig(Location location, boolean setPitchYaw) {
|
||||
if(location == null) {
|
||||
return null;
|
||||
}
|
||||
ConfigurationSection result = new YamlConfiguration();
|
||||
result.set("world", location.getWorld().getName());
|
||||
result.set("x", location.getX());
|
||||
result.set("y", location.getY());
|
||||
result.set("z", location.getZ());
|
||||
if(setPitchYaw) {
|
||||
result.set("yaw", Float.toString(location.getYaw()));
|
||||
result.set("pitch", Float.toString(location.getPitch()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a map from a location, to save it in the config (without pitch and yaw)
|
||||
* @param location The location to transform
|
||||
* @return The map with the location values
|
||||
*/
|
||||
public static ConfigurationSection locationToConfig(Location location) {
|
||||
return locationToConfig(location, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a location from a map, reconstruction from the config values
|
||||
* @param config The config section to reconstruct from
|
||||
* @return The location
|
||||
*/
|
||||
public static Location configToLocation(ConfigurationSection config) {
|
||||
if(config == null
|
||||
|| !config.isString("world")
|
||||
|| !config.isDouble("x")
|
||||
|| !config.isDouble("y")
|
||||
|| !config.isDouble("z")
|
||||
|| Bukkit.getWorld(config.getString("world")) == null) {
|
||||
return null;
|
||||
}
|
||||
Location result = new Location(
|
||||
Bukkit.getWorld(config.getString("world")),
|
||||
config.getDouble("x"),
|
||||
config.getDouble("y"),
|
||||
config.getDouble("z"));
|
||||
if(config.isString("yaw") && config.isString("pitch")) {
|
||||
result.setPitch(Float.parseFloat(config.getString("pitch")));
|
||||
result.setYaw(Float.parseFloat(config.getString("yaw")));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a comma-separated list
|
||||
* @param input Collection of object which should be concatenated with comma's in between
|
||||
* @return Innput object concatenated with comma's in between
|
||||
*/
|
||||
public static String createCommaSeparatedList(Collection<?> input) {
|
||||
String result = "";
|
||||
boolean first = true;
|
||||
for(Object object : input) {
|
||||
if(object != null) {
|
||||
if(first) {
|
||||
first = false;
|
||||
result += object.toString();
|
||||
} else {
|
||||
result += ", " + object.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert milliseconds to ticks
|
||||
* @param milliseconds Milliseconds to convert
|
||||
* @return milliseconds divided by 50 (20 ticks per second)
|
||||
*/
|
||||
public static long millisToTicks(long milliseconds) {
|
||||
return milliseconds/50;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert milliseconds to a human readable format
|
||||
* @param milliseconds The amount of milliseconds to convert
|
||||
* @return A formatted string based on the language file
|
||||
*/
|
||||
public static String millisToHumanFormat(long milliseconds) {
|
||||
long timeLeft = milliseconds+500;
|
||||
// To seconds
|
||||
timeLeft = timeLeft/1000;
|
||||
if(timeLeft <= 0) {
|
||||
return Message.fromKey("timeleft-ended").getPlain();
|
||||
} else if(timeLeft == 1) {
|
||||
return Message.fromKey("timeleft-second").replacements(timeLeft).getPlain();
|
||||
} else if(timeLeft <= 120) {
|
||||
return Message.fromKey("timeleft-seconds").replacements(timeLeft).getPlain();
|
||||
}
|
||||
// To minutes
|
||||
timeLeft = timeLeft/60;
|
||||
if(timeLeft <= 120) {
|
||||
return Message.fromKey("timeleft-minutes").replacements(timeLeft).getPlain();
|
||||
}
|
||||
// To hours
|
||||
timeLeft = timeLeft/60;
|
||||
if(timeLeft <= 48) {
|
||||
return Message.fromKey("timeleft-hours").replacements(timeLeft).getPlain();
|
||||
}
|
||||
// To days
|
||||
timeLeft = timeLeft/24;
|
||||
if(timeLeft <= 60) {
|
||||
return Message.fromKey("timeleft-days").replacements(timeLeft).getPlain();
|
||||
}
|
||||
// To months
|
||||
timeLeft = timeLeft/30;
|
||||
if(timeLeft <= 24) {
|
||||
return Message.fromKey("timeleft-months").replacements(timeLeft).getPlain();
|
||||
}
|
||||
// To years
|
||||
timeLeft = timeLeft/12;
|
||||
return Message.fromKey("timeleft-years").replacements(timeLeft).getPlain();
|
||||
}
|
||||
|
||||
private static final BlockFace[] facings = {BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST};
|
||||
|
||||
/**
|
||||
* Get the facing direction based on the yaw
|
||||
* @param yaw The horizontal angle that for example the player is looking
|
||||
* @return The Block Face of the angle
|
||||
*/
|
||||
public static BlockFace yawToFacing(float yaw) {
|
||||
return facings[Math.round(yaw / 45f) & 0x7];
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// Methods to get WorldGuard or AreaShop regions by location or selection
|
||||
// ======================================================================
|
||||
/**
|
||||
* Get all AreaShop regions intersecting with a WorldEdit selection
|
||||
* @param selection The selection to check
|
||||
* @return A list with all the AreaShop regions intersecting with the selection
|
||||
*/
|
||||
public static List<GeneralRegion> getASRegionsInSelection(Selection selection) {
|
||||
ArrayList<GeneralRegion> result = new ArrayList<>();
|
||||
for(ProtectedRegion region : getWERegionsInSelection(selection)) {
|
||||
GeneralRegion asRegion = AreaShop.getInstance().getFileManager().getRegion(region.getId());
|
||||
if(asRegion != null) {
|
||||
result.add(asRegion);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Get all AreaShop regions containing a location
|
||||
* @param location The location to check
|
||||
* @return A list with all the AreaShop regions that contain the location
|
||||
*/
|
||||
public static List<GeneralRegion> getASRegionsByLocation(Location location) {
|
||||
Selection selection = new CuboidSelection(location.getWorld(), location, location);
|
||||
return getASRegionsInSelection(selection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all WorldGuard regions intersecting with a WorldEdit selection
|
||||
* @param selection The selection to check
|
||||
* @return A list with all the WorldGuard regions intersecting with the selection
|
||||
*/
|
||||
public static List<ProtectedRegion> getWERegionsInSelection(Selection selection) {
|
||||
// Get all regions inside or intersecting with the WorldEdit selection of the player
|
||||
World world = selection.getWorld();
|
||||
RegionManager regionManager = AreaShop.getInstance().getWorldGuard().getRegionManager(world);
|
||||
ArrayList<ProtectedRegion> result = new ArrayList<>();
|
||||
Location selectionMin = selection.getMinimumPoint();
|
||||
Location selectionMax = selection.getMaximumPoint();
|
||||
for(ProtectedRegion region : regionManager.getRegions().values()) {
|
||||
BlockVector regionMin = region.getMinimumPoint();
|
||||
BlockVector regionMax = region.getMaximumPoint();
|
||||
if(
|
||||
( // x part, resolves to true if the selection and region overlap anywhere on the x-axis
|
||||
(regionMin.getBlockX() <= selectionMax.getBlockX() && regionMin.getBlockX() >= selectionMin.getBlockX())
|
||||
|| (regionMax.getBlockX() <= selectionMax.getBlockX() && regionMax.getBlockX() >= selectionMin.getBlockX())
|
||||
|| (selectionMin.getBlockX() >= regionMin.getBlockX() && selectionMin.getBlockX() <= regionMax.getBlockX())
|
||||
|| (selectionMax.getBlockX() >= regionMin.getBlockX() && selectionMax.getBlockX() <= regionMax.getBlockX())
|
||||
) && ( // Y part, resolves to true if the selection and region overlap anywhere on the y-axis
|
||||
(regionMin.getBlockY() <= selectionMax.getBlockY() && regionMin.getBlockY() >= selectionMin.getBlockY())
|
||||
|| (regionMax.getBlockY() <= selectionMax.getBlockY() && regionMax.getBlockY() >= selectionMin.getBlockY())
|
||||
|| (selectionMin.getBlockY() >= regionMin.getBlockY() && selectionMin.getBlockY() <= regionMax.getBlockY())
|
||||
|| (selectionMax.getBlockY() >= regionMin.getBlockY() && selectionMax.getBlockY() <= regionMax.getBlockY())
|
||||
) && ( // Z part, resolves to true if the selection and region overlap anywhere on the z-axis
|
||||
(regionMin.getBlockZ() <= selectionMax.getBlockZ() && regionMin.getBlockZ() >= selectionMin.getBlockZ())
|
||||
|| (regionMax.getBlockZ() <= selectionMax.getBlockZ() && regionMax.getBlockZ() >= selectionMin.getBlockZ())
|
||||
|| (selectionMin.getBlockZ() >= regionMin.getBlockZ() && selectionMin.getBlockZ() <= regionMax.getBlockZ())
|
||||
|| (selectionMax.getBlockZ() >= regionMin.getBlockZ() && selectionMax.getBlockZ() <= regionMax.getBlockZ())
|
||||
)
|
||||
) {
|
||||
result.add(region);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of regions around a location
|
||||
* - Returns highest priority, child instead of parent regions
|
||||
* @param location The location to check for regions
|
||||
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
|
||||
*/
|
||||
public static List<ProtectedRegion> getApplicableRegions(Location location) {
|
||||
List<ProtectedRegion> result = new ArrayList<>();
|
||||
Set<ProtectedRegion> regions = AreaShop.getInstance().getWorldGuardHandler().getApplicableRegionsSet(location);
|
||||
if(regions != null) {
|
||||
boolean first = true;
|
||||
for(ProtectedRegion pr : regions) {
|
||||
if(first) {
|
||||
result.add(pr);
|
||||
first = false;
|
||||
} else {
|
||||
if(pr.getPriority() > result.get(0).getPriority()) {
|
||||
result.clear();
|
||||
result.add(pr);
|
||||
} else if(pr.getParent() != null && pr.getParent().equals(result.get(0))) {
|
||||
result.clear();
|
||||
result.add(pr);
|
||||
} else {
|
||||
result.add(pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most important rental AreaShop regions
|
||||
* - Returns highest priority, child instead of parent regions
|
||||
* @param location The location to check for regions
|
||||
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
|
||||
*/
|
||||
public static List<RentRegion> getApplicableRentRegions(Location location) {
|
||||
List<RentRegion> result = new ArrayList<>();
|
||||
for(GeneralRegion region : getApplicableASRegions(location, GeneralRegion.RegionType.RENT)) {
|
||||
result.add((RentRegion)region);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most important buy AreaShop regions
|
||||
* - Returns highest priority, child instead of parent regions
|
||||
* @param location The location to check for regions
|
||||
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
|
||||
*/
|
||||
public static List<BuyRegion> getApplicableBuyRegions(Location location) {
|
||||
List<BuyRegion> result = new ArrayList<>();
|
||||
for(GeneralRegion region : getApplicableASRegions(location, GeneralRegion.RegionType.BUY)) {
|
||||
result.add((BuyRegion)region);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most important AreaShop regions
|
||||
* - Returns highest priority, child instead of parent regions
|
||||
* @param location The location to check for regions
|
||||
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
|
||||
*/
|
||||
public static List<GeneralRegion> getAllApplicableRegions(Location location) {
|
||||
return getApplicableASRegions(location, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most important AreaShop regions
|
||||
* - Returns highest priority, child instead of parent regions
|
||||
* @param location The location to check for regions
|
||||
* @param type The type of regions to look for, null for all
|
||||
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
|
||||
*/
|
||||
public static List<GeneralRegion> getApplicableASRegions(Location location, GeneralRegion.RegionType type) {
|
||||
List<GeneralRegion> result = new ArrayList<>();
|
||||
Set<ProtectedRegion> regions = AreaShop.getInstance().getWorldGuardHandler().getApplicableRegionsSet(location);
|
||||
if(regions != null) {
|
||||
List<GeneralRegion> candidates = new ArrayList<>();
|
||||
for(ProtectedRegion pr : regions) {
|
||||
GeneralRegion region = AreaShop.getInstance().getFileManager().getRegion(pr.getId());
|
||||
if(region != null && (
|
||||
(type == GeneralRegion.RegionType.RENT && region.isRentRegion())
|
||||
|| (type == GeneralRegion.RegionType.BUY && region.isBuyRegion())
|
||||
|| type == null)) {
|
||||
candidates.add(region);
|
||||
}
|
||||
}
|
||||
boolean first = true;
|
||||
for(GeneralRegion region : candidates) {
|
||||
if(region == null) {
|
||||
AreaShop.debug("skipped null region");
|
||||
continue;
|
||||
}
|
||||
if(first) {
|
||||
result.add(region);
|
||||
first = false;
|
||||
} else {
|
||||
if(region.getRegion().getPriority() > result.get(0).getRegion().getPriority()) {
|
||||
result.clear();
|
||||
result.add(region);
|
||||
} else if(region.getRegion().getParent() != null && region.getRegion().getParent().equals(result.get(0).getRegion())) {
|
||||
result.clear();
|
||||
result.add(region);
|
||||
} else {
|
||||
result.add(region);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert color and formatting codes to bukkit values
|
||||
* @param input Start string with color and formatting codes in it
|
||||
* @return String with the color and formatting codes in the bukkit format
|
||||
*/
|
||||
public static String applyColors(String input) {
|
||||
String result = null;
|
||||
if(input != null) {
|
||||
result = ChatColor.translateAlternateColorCodes('&', input);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format the currency amount with the characters before and after
|
||||
* @param amount Amount of money to format
|
||||
* @return Currency character format string
|
||||
*/
|
||||
public static String formatCurrency(double amount) {
|
||||
String before = config.getString("moneyCharacter");
|
||||
before = before.replace(AreaShop.currencyEuro, "\u20ac");
|
||||
String after = config.getString("moneyCharacterAfter");
|
||||
after = after.replace(AreaShop.currencyEuro, "\u20ac");
|
||||
String result;
|
||||
// Check for infinite and NaN
|
||||
if(Double.isInfinite(amount)) {
|
||||
result = "\u221E"; // Infinite symbol
|
||||
} else if(Double.isNaN(amount)) {
|
||||
result = "NaN";
|
||||
} else {
|
||||
// Add metric
|
||||
double metricAbove = config.getDouble("metricSuffixesAbove");
|
||||
if(metricAbove != -1 && amount >= metricAbove) {
|
||||
if(amount >= 1000000000000000000000000.0) {
|
||||
amount = amount/1000000000000000000000000.0;
|
||||
after = "Y"+after;
|
||||
} else if(amount >= 1000000000000000000000.0) {
|
||||
amount = amount/1000000000000000000000.0;
|
||||
after = "Z"+after;
|
||||
} else if(amount >= 1000000000000000000.0) {
|
||||
amount = amount/1000000000000000000.0;
|
||||
after = "E"+after;
|
||||
} else if(amount >= 1000000000000000.0) {
|
||||
amount = amount/1000000000000000.0;
|
||||
after = "P"+after;
|
||||
} else if(amount >= 1000000000000.0) {
|
||||
amount = amount/1000000000000.0;
|
||||
after = "T"+after;
|
||||
} else if(amount >= 1000000000.0) {
|
||||
amount = amount/1000000000.0;
|
||||
after = "G"+after;
|
||||
} else if(amount >= 1000000.0) {
|
||||
amount = amount/1000000.0;
|
||||
after = "M"+after;
|
||||
} else if(amount >= 1000.0) {
|
||||
amount = amount/1000.0;
|
||||
after = "k"+after;
|
||||
}
|
||||
BigDecimal bigDecimal = new BigDecimal(amount);
|
||||
if(bigDecimal.toString().contains(".")) {
|
||||
int frontLength = bigDecimal.toString().substring(0, bigDecimal.toString().indexOf('.')).length();
|
||||
bigDecimal = bigDecimal.setScale(config.getInt("fractionalNumbers")+(3-frontLength), RoundingMode.HALF_UP);
|
||||
}
|
||||
result = bigDecimal.toString();
|
||||
} else {
|
||||
BigDecimal bigDecimal = new BigDecimal(amount);
|
||||
bigDecimal = bigDecimal.setScale(config.getInt("fractionalNumbers"), RoundingMode.HALF_UP);
|
||||
amount = bigDecimal.doubleValue();
|
||||
result = bigDecimal.toString();
|
||||
if(config.getBoolean("hideEmptyFractionalPart") && (amount%1.0) == 0.0 && result.contains(".")) {
|
||||
result = result.substring(0, result.indexOf('.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
result = result.replace(".", config.getString("decimalMark"));
|
||||
return before+result+after;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the string is a correct time period
|
||||
* @param time String that has to be checked
|
||||
* @return true if format is correct, false if not
|
||||
*/
|
||||
public static boolean checkTimeFormat(String time) {
|
||||
// Check if the string is not empty and check the length
|
||||
if(time == null || time.length() <= 1 || time.indexOf(' ') == -1 || time.indexOf(' ') >= (time.length()-1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the suffix is one of these values
|
||||
String suffix = time.substring(time.indexOf(' ')+1, time.length());
|
||||
if(!identifiers.contains(suffix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the part before the space is a number
|
||||
String prefix = time.substring(0, (time.indexOf(' ')));
|
||||
return prefix.matches("\\d+");
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode to tranlate a duration string to a millisecond value
|
||||
* @param duration The duration string
|
||||
* @return The duration in milliseconds translated from the durationstring, or if it is invalid then 0
|
||||
*/
|
||||
public static long durationStringToLong(String duration) {
|
||||
if(duration == null) {
|
||||
return 0;
|
||||
} else if(duration.equalsIgnoreCase("disabled") || duration.equalsIgnoreCase("unlimited")) {
|
||||
return -1;
|
||||
} else if(duration.indexOf(' ') == -1) {
|
||||
return 0;
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(0);
|
||||
|
||||
String durationString = duration.substring(duration.indexOf(' ')+1, duration.length());
|
||||
int durationInt = 0;
|
||||
try {
|
||||
durationInt = Integer.parseInt(duration.substring(0, duration.indexOf(' ')));
|
||||
} catch(NumberFormatException exception) {
|
||||
// No Number found, add zero
|
||||
}
|
||||
|
||||
if(seconds.contains(durationString)) {
|
||||
calendar.add(Calendar.SECOND, durationInt);
|
||||
} else if(minutes.contains(durationString)) {
|
||||
calendar.add(Calendar.MINUTE, durationInt);
|
||||
} else if(hours.contains(durationString)) {
|
||||
calendar.add(Calendar.HOUR, durationInt);
|
||||
} else if(days.contains(durationString)) {
|
||||
calendar.add(Calendar.DAY_OF_MONTH, durationInt);
|
||||
} else if(weeks.contains(durationString)) {
|
||||
calendar.add(Calendar.DAY_OF_MONTH, durationInt*7);
|
||||
} else if(months.contains(durationString)) {
|
||||
calendar.add(Calendar.MONTH, durationInt);
|
||||
} else if(years.contains(durationString)) {
|
||||
calendar.add(Calendar.YEAR, durationInt);
|
||||
}
|
||||
return calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
// LEGACY TIME INPUT CONVERSION
|
||||
|
||||
/**
|
||||
* Get setting from config that could be only a number indicating seconds
|
||||
* or a string indicating a duration string
|
||||
* @param path Path of the setting to read
|
||||
* @return milliseconds that the setting indicates
|
||||
*/
|
||||
public static long getDurationFromSecondsOrString(String path) {
|
||||
if(config.isLong(path) || config.isInt(path)) {
|
||||
long setting = config.getLong(path);
|
||||
if(setting != -1) {
|
||||
setting = setting*1000;
|
||||
}
|
||||
return setting;
|
||||
} else {
|
||||
return durationStringToLong(config.getString(path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting from config that could be only a number indicating minutes
|
||||
* or a string indicating a duration string
|
||||
* @param path Path of the setting to read
|
||||
* @return milliseconds that the setting indicates
|
||||
*/
|
||||
public static long getDurationFromMinutesOrString(String path) {
|
||||
if(config.isLong(path) || config.isInt(path)) {
|
||||
long setting = config.getLong(path);
|
||||
if(setting != -1) {
|
||||
setting = setting*60*1000;
|
||||
}
|
||||
return setting;
|
||||
} else {
|
||||
return durationStringToLong(config.getString(path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a time setting that could be minutes or a duration string
|
||||
* @param input The string to parse
|
||||
* @return milliseconds that the string indicates
|
||||
*/
|
||||
public static long getDurationFromMinutesOrStringInput(String input) {
|
||||
long number;
|
||||
try {
|
||||
number = Long.parseLong(input);
|
||||
if(number != -1) {
|
||||
number = number*60*1000;
|
||||
}
|
||||
return number;
|
||||
} catch(NumberFormatException e) {
|
||||
return durationStringToLong(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a start of the message with a maximum length
|
||||
* @param message The message
|
||||
* @param maximumLength The maximum length to return
|
||||
* @return The start of the message with at most maximumLength characters
|
||||
*/
|
||||
public static String getMessageStart(Message message, int maximumLength) {
|
||||
String messageStart = "";
|
||||
for(int i = 0; i < message.getRaw().size() && messageStart.length() < maximumLength; i++) {
|
||||
messageStart += message.getRaw().get(i).substring(0, Math.min(maximumLength, message.getRaw().get(i).length()));
|
||||
}
|
||||
return messageStart.substring(0, Math.min(maximumLength, messageStart.length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a time setting that could be seconds or a duration string
|
||||
* @param input The string to parse
|
||||
* @return seconds that the string indicates
|
||||
*/
|
||||
public static long getDurationFromSecondsOrStringInput(String input) {
|
||||
long number;
|
||||
try {
|
||||
number = Long.parseLong(input);
|
||||
if(number != -1) {
|
||||
number = number*1000;
|
||||
}
|
||||
return number;
|
||||
} catch(NumberFormatException e) {
|
||||
return durationStringToLong(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an input is numeric
|
||||
* @param input The input to check
|
||||
* @return true if the input is numeric, otherwise false
|
||||
*/
|
||||
public static boolean isNumeric(String input) {
|
||||
try {
|
||||
Integer.parseInt(input);
|
||||
return true;
|
||||
} catch(NumberFormatException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NAME <-> UUID CONVERSION
|
||||
|
||||
/**
|
||||
* Conversion to name by uuid
|
||||
* @param uuid The uuid in string format
|
||||
* @return the name of the player
|
||||
*/
|
||||
public static String toName(String uuid) {
|
||||
String result = "";
|
||||
if(uuid != null) {
|
||||
try {
|
||||
UUID parsed = UUID.fromString(uuid);
|
||||
result = toName(parsed);
|
||||
} catch(IllegalArgumentException e) {
|
||||
// Incorrect UUID
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion to name by uuid object
|
||||
* @param uuid The uuid in string format
|
||||
* @return the name of the player
|
||||
*/
|
||||
public static String toName(UUID uuid) {
|
||||
if(uuid == null) {
|
||||
return "";
|
||||
} else {
|
||||
String name = Bukkit.getOfflinePlayer(uuid).getName();
|
||||
if(name != null) {
|
||||
return name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion from name to uuid
|
||||
* @param name The name of the player
|
||||
* @return The uuid of the player
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Fake deprecation by Bukkit to inform developers, method will stay
|
||||
public static String toUUID(String name) {
|
||||
if(name == null) {
|
||||
return null;
|
||||
} else {
|
||||
return Bukkit.getOfflinePlayer(name).getUniqueId().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +1,43 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AddCommand extends CommandAreaShop {
|
||||
|
||||
public AddCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop add";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.createrent") || target.hasPermission("areashop.createbuy")) {
|
||||
if(target.hasPermission("areashop.createrent")
|
||||
|| target.hasPermission("areashop.createrent.member")
|
||||
|| target.hasPermission("areashop.createrent.owner")
|
||||
|
||||
|| target.hasPermission("areashop.createbuy")
|
||||
|| target.hasPermission("areashop.createbuy.member")
|
||||
|| target.hasPermission("areashop.createbuy.owner")) {
|
||||
return "help-add";
|
||||
}
|
||||
return null;
|
||||
@@ -39,22 +45,22 @@ public class AddCommand extends CommandAreaShop {
|
||||
|
||||
@Override
|
||||
public void execute(final CommandSender sender, final String[] args) {
|
||||
if( !sender.hasPermission("areashop.createrent")
|
||||
if(!sender.hasPermission("areashop.createrent")
|
||||
&& !sender.hasPermission("areashop.createrent.member")
|
||||
&& !sender.hasPermission("areashop.createrent.owner")
|
||||
|
||||
|
||||
&& !sender.hasPermission("areashop.createbuy")
|
||||
&& !sender.hasPermission("areashop.createbuy.member")
|
||||
&& !sender.hasPermission("areashop.createbuy.owner")) {
|
||||
plugin.message(sender, "add-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 2 || args[1] == null || (!"rent".equals(args[1].toLowerCase()) && !"buy".equals(args[1].toLowerCase()))) {
|
||||
|
||||
if(args.length < 2 || args[1] == null || (!"rent".equalsIgnoreCase(args[1]) && !"buy".equalsIgnoreCase(args[1]))) {
|
||||
plugin.message(sender, "add-help");
|
||||
return;
|
||||
}
|
||||
List<ProtectedRegion> regions = new ArrayList<>();
|
||||
Map<String, ProtectedRegion> regions = new HashMap<>();
|
||||
World world;
|
||||
Player player = null;
|
||||
if(sender instanceof Player) {
|
||||
@@ -64,15 +70,15 @@ public class AddCommand extends CommandAreaShop {
|
||||
if(player == null) {
|
||||
plugin.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Selection selection = plugin.getWorldEdit().getSelection(player);
|
||||
}
|
||||
WorldEditSelection selection = plugin.getWorldEditHandler().getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
plugin.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
world = selection.getWorld();
|
||||
regions = Utils.getWERegionsInSelection(selection);
|
||||
if(regions.size() == 0) {
|
||||
regions = Utils.getWorldEditRegionsInSelection(selection).stream().collect(Collectors.toMap(ProtectedRegion::getId, region -> region));
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(player, "cmd-noWERegionsFound");
|
||||
return;
|
||||
}
|
||||
@@ -99,113 +105,187 @@ public class AddCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtectedRegion region = plugin.getWorldGuard().getRegionManager(world).getRegion(args[2]);
|
||||
ProtectedRegion region = plugin.getRegionManager(world).getRegion(args[2]);
|
||||
if(region == null) {
|
||||
plugin.message(sender, "add-noRegion", args[2]);
|
||||
plugin.message(sender, "cmd-noRegion", args[2]);
|
||||
return;
|
||||
}
|
||||
regions.add(region);
|
||||
regions.put(args[2], region);
|
||||
}
|
||||
final boolean isRent = "rent".equals(args[1].toLowerCase());
|
||||
final List<ProtectedRegion> finalRegions = regions;
|
||||
final boolean isRent = "rent".equalsIgnoreCase(args[1]);
|
||||
final Player finalPlayer = player;
|
||||
final World finalWorld = world;
|
||||
AreaShop.debug("Starting add task with " + regions.size() + " regions");
|
||||
new BukkitRunnable() {
|
||||
private int current = 0;
|
||||
private TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
private TreeSet<GeneralRegion> regionsAlready = new TreeSet<>();
|
||||
private TreeSet<String> namesBlacklisted = new TreeSet<>();
|
||||
private TreeSet<String> namesNoPermission = new TreeSet<>();
|
||||
private TreeSet<String> namesExternal = new TreeSet<>();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i=0; i<plugin.getConfig().getInt("adding.regionsPerTick"); i++) {
|
||||
if(current < finalRegions.size()) {
|
||||
ProtectedRegion region = finalRegions.get(current);
|
||||
// Determine if the player is an owner or member of the region
|
||||
boolean isMember = finalPlayer != null && plugin.getWorldGuardHandler().containsMember(region, finalPlayer.getUniqueId());
|
||||
boolean isOwner = finalPlayer != null && plugin.getWorldGuardHandler().containsMember(region, finalPlayer.getUniqueId());
|
||||
String type;
|
||||
if(isRent) {
|
||||
type = "rent";
|
||||
} else {
|
||||
type = "buy";
|
||||
|
||||
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsAlready = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsAlreadyOtherWorld = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsRentCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
TreeSet<GeneralRegion> regionsBuyCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
TreeSet<String> namesBlacklisted = new TreeSet<>();
|
||||
TreeSet<String> namesNoPermission = new TreeSet<>();
|
||||
TreeSet<String> namesAddCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
Utils.runAsBatches(regions.entrySet(),
|
||||
plugin.getConfig().getInt("adding.regionsPerTick"),
|
||||
(regionEntry) -> {
|
||||
String regionName = regionEntry.getKey();
|
||||
ProtectedRegion region = regionEntry.getValue();
|
||||
// Determine if the player is an owner or member of the region
|
||||
boolean isMember = finalPlayer != null && plugin.getWorldGuardHandler().containsMember(region, finalPlayer.getUniqueId());
|
||||
boolean isOwner = finalPlayer != null && plugin.getWorldGuardHandler().containsOwner(region, finalPlayer.getUniqueId());
|
||||
String type;
|
||||
if(isRent) {
|
||||
type = "rent";
|
||||
} else {
|
||||
type = "buy";
|
||||
}
|
||||
FileManager.AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, world, isRent ? GeneralRegion.RegionType.RENT : GeneralRegion.RegionType.BUY);
|
||||
if(result == FileManager.AddResult.ALREADYADDED) {
|
||||
regionsAlready.add(plugin.getFileManager().getRegion(regionName));
|
||||
} else if(result == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
||||
regionsAlreadyOtherWorld.add(plugin.getFileManager().getRegion(regionName));
|
||||
} else if(result == FileManager.AddResult.BLACKLISTED) {
|
||||
namesBlacklisted.add(regionName);
|
||||
} else if(result == FileManager.AddResult.NOPERMISSION) {
|
||||
namesNoPermission.add(regionName);
|
||||
} else {
|
||||
// Check if the player should be landlord
|
||||
boolean landlord = (!sender.hasPermission("areashop.create" + type)
|
||||
&& ((sender.hasPermission("areashop.create" + type + ".owner") && isOwner)
|
||||
|| (sender.hasPermission("areashop.create" + type + ".member") && isMember)));
|
||||
List<UUID> existing = new ArrayList<>();
|
||||
existing.addAll(plugin.getWorldGuardHandler().getOwners(region).asUniqueIdList());
|
||||
existing.addAll(plugin.getWorldGuardHandler().getMembers(region).asUniqueIdList());
|
||||
|
||||
AreaShop.debug("regionAddLandlordStatus:", regionName,
|
||||
"landlord:", landlord,
|
||||
"existing:", existing,
|
||||
"isMember:", isMember,
|
||||
"isOwner:", isOwner,
|
||||
"createPermission:", sender.hasPermission("areashop.create" + type),
|
||||
"ownerPermission:", sender.hasPermission("areashop.create" + type + ".owner"),
|
||||
"memberPermission:", sender.hasPermission("areashop.create" + type + ".member"));
|
||||
|
||||
if(isRent) {
|
||||
RentRegion rent = new RentRegion(regionName, world);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
rent.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
|
||||
}
|
||||
FileManager.AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, isRent ? GeneralRegion.RegionType.RENT : GeneralRegion.RegionType.BUY);
|
||||
if(result == FileManager.AddResult.ALREADYADDED) {
|
||||
regionsAlready.add(plugin.getFileManager().getRegion(region.getId()));
|
||||
} else if(result == FileManager.AddResult.BLACKLISTED) {
|
||||
namesBlacklisted.add(region.getId());
|
||||
} else if(result == FileManager.AddResult.NOPERMISSION) {
|
||||
namesNoPermission.add(region.getId());
|
||||
} else {
|
||||
// Check if the player should be landlord
|
||||
boolean landlord = (!sender.hasPermission("areashop.create" + type)
|
||||
&& ((sender.hasPermission("areashop.create" + type + ".owner") && isOwner)
|
||||
|| (sender.hasPermission("areashop.create" + type + ".member") && isMember)));
|
||||
if(isRent) {
|
||||
RentRegion rent = new RentRegion(plugin, region.getId(), finalWorld);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
rent.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
|
||||
}
|
||||
// Run commands
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
plugin.getFileManager().addRent(rent);
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
|
||||
rent.update();
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(rent);
|
||||
if (event.isCancelled()) {
|
||||
namesAddCancelled.add(rent.getName());
|
||||
return;
|
||||
}
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
rent.update();
|
||||
|
||||
// Run commands
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
regionsSuccess.add(rent);
|
||||
// Add existing owners/members if any
|
||||
if(!landlord && !existing.isEmpty()) {
|
||||
UUID rentBy = existing.remove(0);
|
||||
OfflinePlayer rentByPlayer = Bukkit.getOfflinePlayer(rentBy);
|
||||
|
||||
RentingRegionEvent rentingRegionEvent = new RentingRegionEvent(rent, rentByPlayer, false);
|
||||
Bukkit.getPluginManager().callEvent(rentingRegionEvent);
|
||||
if(rentingRegionEvent.isCancelled()) {
|
||||
regionsRentCancelled.add(rent);
|
||||
} else {
|
||||
BuyRegion buy = new BuyRegion(plugin, region.getId(), finalWorld);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
buy.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
|
||||
// Add values to the rent and send it to FileManager
|
||||
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
|
||||
rent.setRenter(rentBy);
|
||||
rent.updateLastActiveTime();
|
||||
|
||||
// Fire schematic event and updated times extended
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.RENTED);
|
||||
|
||||
// Add others as friends
|
||||
for(UUID friend : existing) {
|
||||
rent.getFriendsFeature().addFriend(friend, null);
|
||||
}
|
||||
// Run commands
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
|
||||
plugin.getFileManager().addBuy(buy);
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
|
||||
buy.update();
|
||||
|
||||
// Run commands
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
regionsSuccess.add(buy);
|
||||
rent.notifyAndUpdate(new RentedRegionEvent(rent, false));
|
||||
}
|
||||
}
|
||||
current++;
|
||||
|
||||
regionsSuccess.add(rent);
|
||||
} else {
|
||||
BuyRegion buy = new BuyRegion(regionName, world);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
buy.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
|
||||
}
|
||||
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(buy);
|
||||
if (event.isCancelled()) {
|
||||
namesAddCancelled.add(buy.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
buy.update();
|
||||
|
||||
// Add existing owners/members if any
|
||||
if(!landlord && !existing.isEmpty()) {
|
||||
UUID buyBy = existing.remove(0);
|
||||
OfflinePlayer buyByPlayer = Bukkit.getOfflinePlayer(buyBy);
|
||||
|
||||
BuyingRegionEvent buyingRegionEvent = new BuyingRegionEvent(buy, buyByPlayer);
|
||||
Bukkit.getPluginManager().callEvent(buyingRegionEvent);
|
||||
if(buyingRegionEvent.isCancelled()) {
|
||||
regionsBuyCancelled.add(buy);
|
||||
} else {
|
||||
// Set the owner
|
||||
buy.setBuyer(buyBy);
|
||||
buy.updateLastActiveTime();
|
||||
|
||||
// Update everything
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.BOUGHT);
|
||||
|
||||
// Add others as friends
|
||||
for (UUID friend : existing) {
|
||||
buy.getFriendsFeature().addFriend(friend, null);
|
||||
}
|
||||
|
||||
buy.notifyAndUpdate(new BoughtRegionEvent(buy));
|
||||
}
|
||||
}
|
||||
|
||||
regionsSuccess.add(buy);
|
||||
}
|
||||
}
|
||||
if(current >= finalRegions.size()) {
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
plugin.message(sender, "add-success", args[1], Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(!regionsAlready.isEmpty()) {
|
||||
plugin.message(sender, "add-failed", Utils.combinedMessage(regionsAlready, "region"));
|
||||
}
|
||||
if(!namesBlacklisted.isEmpty()) {
|
||||
plugin.message(sender, "add-blacklisted", Utils.createCommaSeparatedList(namesBlacklisted));
|
||||
}
|
||||
if(!namesNoPermission.isEmpty()) {
|
||||
plugin.message(sender, "add-noPermissionRegions", Utils.createCommaSeparatedList(namesNoPermission));
|
||||
plugin.message(sender, "add-noPermissionOwnerMember");
|
||||
}
|
||||
this.cancel();
|
||||
}, false).thenAccept(
|
||||
(success) -> {
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
plugin.message(sender, "add-success", args[1], Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 1, 1);
|
||||
if(!regionsAlready.isEmpty()) {
|
||||
plugin.message(sender, "add-failed", Utils.combinedMessage(regionsAlready, "region"));
|
||||
}
|
||||
if(!regionsAlreadyOtherWorld.isEmpty()) {
|
||||
plugin.message(sender, "add-failedOtherWorld", Utils.combinedMessage(regionsAlreadyOtherWorld, "region"));
|
||||
}
|
||||
if(!regionsRentCancelled.isEmpty()) {
|
||||
plugin.message(sender, "add-rentCancelled", Utils.combinedMessage(regionsRentCancelled, "region"));
|
||||
}
|
||||
if(!regionsBuyCancelled.isEmpty()) {
|
||||
plugin.message(sender, "add-buyCancelled", Utils.combinedMessage(regionsBuyCancelled, "region"));
|
||||
}
|
||||
if(!namesBlacklisted.isEmpty()) {
|
||||
plugin.message(sender, "add-blacklisted", Utils.createCommaSeparatedList(namesBlacklisted));
|
||||
}
|
||||
if(!namesNoPermission.isEmpty()) {
|
||||
plugin.message(sender, "add-noPermissionRegions", Utils.createCommaSeparatedList(namesNoPermission));
|
||||
plugin.message(sender, "add-noPermissionOwnerMember");
|
||||
}
|
||||
if(!namesAddCancelled.isEmpty()) {
|
||||
plugin.message(sender, "add-rentCancelled", Utils.createCommaSeparatedList(namesAddCancelled));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
List<String> result = new LinkedList<>();
|
||||
if(toComplete == 2) {
|
||||
if(sender.hasPermission("areashop.createrent")) {
|
||||
result.add("rent");
|
||||
@@ -217,7 +297,7 @@ public class AddCommand extends CommandAreaShop {
|
||||
if(sender instanceof Player) {
|
||||
Player player = (Player)sender;
|
||||
if(sender.hasPermission("areashop.createrent") || sender.hasPermission("areashop.createbuy")) {
|
||||
for(ProtectedRegion region : plugin.getWorldGuard().getRegionManager(player.getWorld()).getRegions().values()) {
|
||||
for(ProtectedRegion region : plugin.getRegionManager(player.getWorld()).getRegions().values()) {
|
||||
result.add(region.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -15,10 +14,6 @@ import java.util.List;
|
||||
|
||||
public class AddfriendCommand extends CommandAreaShop {
|
||||
|
||||
public AddfriendCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop addfriend";
|
||||
@@ -31,7 +26,7 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
@@ -39,7 +34,7 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "addfriend-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(args.length < 2) {
|
||||
plugin.message(sender, "addfriend-help");
|
||||
return;
|
||||
@@ -47,13 +42,13 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
|
||||
GeneralRegion region;
|
||||
if(args.length <= 2) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -62,7 +57,7 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
region = plugin.getFileManager().getRegion(args[2]);
|
||||
if(region == null) {
|
||||
@@ -71,13 +66,13 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
if(sender.hasPermission("areashop.addfriendall")) {
|
||||
if((region.isRentRegion() && !((RentRegion)region).isRented())
|
||||
|| (region.isBuyRegion() && !((BuyRegion)region).isSold())) {
|
||||
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|
||||
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
|
||||
plugin.message(sender, "addfriend-noOwner", region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(friend.getLastPlayed() == 0 && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
plugin.message(sender, "addfriend-notVisited", args[1], region);
|
||||
return;
|
||||
}
|
||||
@@ -97,7 +92,7 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
if(sender.hasPermission("areashop.addfriend") && sender instanceof Player) {
|
||||
if(region.isOwner((Player)sender)) {
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(friend.getLastPlayed() == 0 && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
plugin.message(sender, "addfriend-notVisited", args[1], region);
|
||||
return;
|
||||
}
|
||||
@@ -122,7 +117,7 @@ public class AddfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.features.SignsFeature;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Sign;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.material.Sign;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -18,104 +21,108 @@ import java.util.Set;
|
||||
|
||||
public class AddsignCommand extends CommandAreaShop {
|
||||
|
||||
public AddsignCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop addsign";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.addsign")) {
|
||||
return "help-addsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop addsign";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.addsign")) {
|
||||
plugin.message(sender, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if (target.hasPermission("areashop.addsign")) {
|
||||
return "help-addsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(player, 100);
|
||||
while(blockIterator.hasNext() && block == null) {
|
||||
Block next = blockIterator.next();
|
||||
if(next.getType() != Material.AIR) {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if(block == null || !(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST)) {
|
||||
plugin.message(sender, "addsign-noSign");
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("areashop.addsign")) {
|
||||
plugin.message(sender, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
|
||||
GeneralRegion region;
|
||||
if(args.length > 1) {
|
||||
// Get region by argument
|
||||
region = plugin.getFileManager().getRegion(args[1]);
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getASRegionsInSelection(new CuboidSelection(block.getWorld(), block.getLocation(), block.getLocation()));
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "addsign-noRegions");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
Sign sign = (Sign)block.getState().getData();
|
||||
String profile = null;
|
||||
if(args.length > 2) {
|
||||
profile = args[2];
|
||||
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
|
||||
if(!profiles.contains(profile)) {
|
||||
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign != null) {
|
||||
plugin.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
|
||||
return;
|
||||
}
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(player, 100);
|
||||
while (blockIterator.hasNext() && block == null) {
|
||||
Block next = blockIterator.next();
|
||||
if (next.getType() != Material.AIR) {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if (block == null || !Materials.isSign(block.getType())) {
|
||||
plugin.message(sender, "addsign-noSign");
|
||||
return;
|
||||
}
|
||||
|
||||
region.getSignsFeature().addSign(block.getLocation(), block.getType(), sign.getFacing(), profile);
|
||||
if(profile == null) {
|
||||
plugin.message(sender, "addsign-success", region);
|
||||
} else {
|
||||
plugin.message(sender, "addsign-successProfile", profile, region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(plugin.getFileManager().getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("signProfiles"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if (args.length > 1) {
|
||||
// Get region by argument
|
||||
region = plugin.getFileManager().getRegion(args[1]);
|
||||
if (region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(block.getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "addsign-noRegions");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
String profile = null;
|
||||
if (args.length > 2) {
|
||||
profile = args[2];
|
||||
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
|
||||
if (!profiles.contains(profile)) {
|
||||
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign != null) {
|
||||
plugin.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockData data = block.getBlockData();
|
||||
final BlockFace rotation;
|
||||
if (data instanceof Sign) {
|
||||
rotation = ((Sign) data).getRotation();
|
||||
} else if (data instanceof WallSign) {
|
||||
rotation = ((WallSign) data).getFacing();
|
||||
} else {
|
||||
rotation = null;
|
||||
}
|
||||
region.getSignsFeature().addSign(block.getLocation(), block.getType(), rotation, profile);
|
||||
if (profile == null) {
|
||||
plugin.message(sender, "addsign-success", region);
|
||||
} else {
|
||||
plugin.message(sender, "addsign-successProfile", profile, region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if (toComplete == 2) {
|
||||
result.addAll(plugin.getFileManager().getRegionNames());
|
||||
} else if (toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("signProfiles"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -11,10 +10,6 @@ import java.util.List;
|
||||
|
||||
public class BuyCommand extends CommandAreaShop {
|
||||
|
||||
public BuyCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop buy";
|
||||
@@ -27,14 +22,14 @@ public class BuyCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.buy")) {
|
||||
plugin.message(sender, "buy-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
@@ -42,16 +37,16 @@ public class BuyCommand extends CommandAreaShop {
|
||||
if(args.length > 1 && args[1] != null) {
|
||||
BuyRegion region = plugin.getFileManager().getBuy(args[1]);
|
||||
if(region == null) {
|
||||
plugin.message(player, "buy-notBuyable");
|
||||
plugin.message(player, "buy-notBuyable", args[1]);
|
||||
} else {
|
||||
region.buy(player);
|
||||
}
|
||||
} else {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
} else {
|
||||
regions.get(0).buy(player);
|
||||
|
||||
@@ -1,68 +1,102 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Abstract class for generalising command classes
|
||||
* Abstract class for generalising command classes.
|
||||
*/
|
||||
public abstract class CommandAreaShop {
|
||||
AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Save the instance of the main plugin class
|
||||
* @param plugin The main plugin
|
||||
*/
|
||||
public CommandAreaShop(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
final AreaShop plugin = AreaShop.getInstance();
|
||||
|
||||
private final Map<String, CommandTime> lastUsed;
|
||||
|
||||
public CommandAreaShop() {
|
||||
lastUsed = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if this Command instance can execute the given command and arguments.
|
||||
* @param command The command to check for execution
|
||||
* @param args The arguments to check
|
||||
* @return true if it can execute the command, false otherwise
|
||||
*/
|
||||
public boolean canExecute(Command command, String[] args) {
|
||||
String commandString = command.getName();
|
||||
for(String argument : args) {
|
||||
commandString += " " + argument;
|
||||
}
|
||||
String commandString = command.getName() + " " + StringUtils.join(args, " ");
|
||||
if(commandString.length() > getCommandStart().length()) {
|
||||
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase() + " ");
|
||||
}
|
||||
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of string to complete a command with (raw list, not matching ones not filtered out)
|
||||
* Get a list of string to complete a command with (raw list, not matching ones not filtered out).
|
||||
* @param toComplete The number of the argument that has to be completed
|
||||
* @param start The already given start of the command
|
||||
* @param sender The CommandSender that wants to tab complete
|
||||
* @param start The already given start of the command
|
||||
* @param sender The CommandSender that wants to tab complete
|
||||
* @return A collection with all the possibilities for argument to complete
|
||||
*/
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the argument that comes after the base command that this command reacts to
|
||||
* Get the argument that comes after the base command that this command reacts to.
|
||||
* @return The string that should be in front of the command for this class to act
|
||||
*/
|
||||
public abstract String getCommandStart();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the correct help string key to be used on the help page
|
||||
* Returns the correct help string key to be used on the help page.
|
||||
* @param target The CommandSender that the help message is for
|
||||
* @return The help message key according to the permissions of the reciever
|
||||
*/
|
||||
public abstract String getHelp(CommandSender target);
|
||||
|
||||
|
||||
/**
|
||||
* Execute a (sub)command if the conditions are met
|
||||
* Execute a (sub)command if the conditions are met.
|
||||
* @param sender The commandSender that executed the command
|
||||
* @param args The arguments that are given
|
||||
* @param args The arguments that are given
|
||||
*/
|
||||
public abstract void execute(CommandSender sender, String[] args);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Confirm a command.
|
||||
* @param sender To confirm it for, or send a message to confirm
|
||||
* @param args Command args
|
||||
* @param message Message to send when confirmation is required
|
||||
* @return true if confirmed, false if confirmation is required
|
||||
*/
|
||||
public boolean confirm(CommandSender sender, String[] args, Message message) {
|
||||
String command = "/" + getCommandStart() + " " + StringUtils.join(args, " ", 1, args.length);
|
||||
long now = System.currentTimeMillis();
|
||||
CommandTime last = lastUsed.get(sender.getName());
|
||||
if(last != null && last.command.equalsIgnoreCase(command) && last.time > (now - 1000 * 60)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
message.prefix().append(Message.fromKey("confirm-yes").replacements(command)).send(sender);
|
||||
lastUsed.put(sender.getName(), new CommandTime(command, now));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class CommandTime {
|
||||
public final String command;
|
||||
public final long time;
|
||||
|
||||
CommandTime(String command, long time) {
|
||||
this.command = command;
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -15,18 +15,14 @@ import java.util.TreeSet;
|
||||
|
||||
public class DelCommand extends CommandAreaShop {
|
||||
|
||||
public DelCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop del";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.destroyrent") || target.hasPermission("areashop.destroybuy")) {
|
||||
if(target.hasPermission("areashop.destroyrent") || target.hasPermission("areashop.destroybuy") || target.hasPermission("areashop.destroyrent.landlord") || target.hasPermission("areashop.destroybuy.landlord")) {
|
||||
return "help-del";
|
||||
}
|
||||
return null;
|
||||
@@ -34,9 +30,9 @@ public class DelCommand extends CommandAreaShop {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if( !sender.hasPermission("areashop.destroybuy")
|
||||
if(!sender.hasPermission("areashop.destroybuy")
|
||||
&& !sender.hasPermission("areashop.destroybuy.landlord")
|
||||
|
||||
|
||||
&& !sender.hasPermission("areashop.destroyrent")
|
||||
&& !sender.hasPermission("areashop.destroyrent.landlord")) {
|
||||
plugin.message(sender, "del-noPermission");
|
||||
@@ -49,43 +45,51 @@ public class DelCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
Selection selection = plugin.getWorldEdit().getSelection(player);
|
||||
WorldEditSelection selection = plugin.getWorldEditHandler().getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
plugin.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
|
||||
if(regions == null || regions.size() == 0) {
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions == null || regions.isEmpty()) {
|
||||
plugin.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
// Start removing the regions that he has permission for
|
||||
ArrayList<String> namesSuccess = new ArrayList<>();
|
||||
TreeSet<GeneralRegion> namesFailed = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsCancelled = new TreeSet<>();
|
||||
for(GeneralRegion region : regions) {
|
||||
boolean isLandlord = region.isLandlord(((Player)sender).getUniqueId());
|
||||
if(region.isRentRegion()) {
|
||||
if(region instanceof RentRegion) {
|
||||
if(!sender.hasPermission("areashop.destroyrent") && !(isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
|
||||
namesFailed.add(region);
|
||||
} else {
|
||||
plugin.getFileManager().removeRent((RentRegion)region, true);
|
||||
namesSuccess.add(region.getName());
|
||||
}
|
||||
} else if(region.isBuyRegion()) {
|
||||
regionsFailed.add(region);
|
||||
continue;
|
||||
}
|
||||
} else if(region instanceof BuyRegion) {
|
||||
if(!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
|
||||
namesFailed.add(region);
|
||||
} else {
|
||||
plugin.getFileManager().removeBuy((BuyRegion)region, true);
|
||||
namesSuccess.add(region.getName());
|
||||
regionsFailed.add(region);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
regionsCancelled.add(region);
|
||||
} else {
|
||||
namesSuccess.add(region.getName());
|
||||
}
|
||||
}
|
||||
// send messages
|
||||
if(namesSuccess.size() != 0) {
|
||||
|
||||
// Send messages
|
||||
if(!namesSuccess.isEmpty()) {
|
||||
plugin.message(sender, "del-success", Utils.createCommaSeparatedList(namesSuccess));
|
||||
}
|
||||
if(namesFailed.size() != 0) {
|
||||
plugin.message(sender, "del-failed", Utils.combinedMessage(namesFailed, "region"));
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
plugin.message(sender, "del-failed", Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
if(!regionsCancelled.isEmpty()) {
|
||||
plugin.message(sender, "del-cancelled", Utils.combinedMessage(regionsCancelled, "region"));
|
||||
}
|
||||
} else {
|
||||
GeneralRegion region = plugin.getFileManager().getRegion(args[1]);
|
||||
@@ -94,26 +98,34 @@ public class DelCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId());
|
||||
if(region.isRentRegion()) {
|
||||
if(region instanceof RentRegion) {
|
||||
// Remove the rent if the player has permission
|
||||
if(sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
|
||||
plugin.getFileManager().removeRent((RentRegion)region, true);
|
||||
plugin.message(sender, "destroy-successRent", region);
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successRent", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionRent", region);
|
||||
}
|
||||
} else if(region.isBuyRegion()) {
|
||||
} else if(region instanceof BuyRegion) {
|
||||
// Remove the buy if the player has permission
|
||||
if(sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
|
||||
plugin.getFileManager().removeBuy((BuyRegion)region, true);
|
||||
plugin.message(sender, "destroy-successBuy", region);
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successBuy", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionBuy", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -15,10 +14,6 @@ import java.util.List;
|
||||
|
||||
public class DelfriendCommand extends CommandAreaShop {
|
||||
|
||||
public DelfriendCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop delfriend";
|
||||
@@ -33,7 +28,7 @@ public class DelfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can remove friends
|
||||
* Check if a person can remove friends.
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can remove friends, otherwise false
|
||||
@@ -48,27 +43,27 @@ public class DelfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
|
||||
plugin.message(sender, "delfriend-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2) {
|
||||
plugin.message(sender, "delfriend-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if(args.length <= 2) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -77,7 +72,7 @@ public class DelfriendCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
region = plugin.getFileManager().getRegion(args[2]);
|
||||
if(region == null) {
|
||||
@@ -86,11 +81,11 @@ public class DelfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
if(sender.hasPermission("areashop.delfriendall")) {
|
||||
if((region.isRentRegion() && !((RentRegion)region).isRented())
|
||||
|| (region.isBuyRegion() && !((BuyRegion)region).isSold())) {
|
||||
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|
||||
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
|
||||
plugin.message(sender, "delfriend-noOwner", region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
plugin.message(sender, "delfriend-notAdded", friend.getName(), region);
|
||||
@@ -120,7 +115,7 @@ public class DelfriendCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.SignsFeature;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -13,15 +14,11 @@ import java.util.List;
|
||||
|
||||
public class DelsignCommand extends CommandAreaShop {
|
||||
|
||||
public DelsignCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop delsign";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.delsign")) {
|
||||
@@ -36,10 +33,10 @@ public class DelsignCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "delsign-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
|
||||
// Get the sign
|
||||
@@ -51,11 +48,11 @@ public class DelsignCommand extends CommandAreaShop {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if(block == null || !(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST)) {
|
||||
if(block == null || !Materials.isSign(block.getType())) {
|
||||
plugin.message(sender, "delsign-noSign");
|
||||
return;
|
||||
}
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign == null) {
|
||||
plugin.message(sender, "delsign-noRegion");
|
||||
return;
|
||||
@@ -63,7 +60,7 @@ public class DelsignCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "delsign-success", regionSign.getRegion());
|
||||
regionSign.remove();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class FindCommand extends CommandAreaShop {
|
||||
|
||||
public FindCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop find";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.find")) {
|
||||
@@ -37,11 +33,11 @@ public class FindCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.find")) {
|
||||
plugin.message(sender, "find-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length <= 1 || args[1] == null || (!args[1].equalsIgnoreCase("buy") && !args[1].equalsIgnoreCase("rent"))) {
|
||||
plugin.message(sender, "find-help");
|
||||
return;
|
||||
@@ -72,31 +68,36 @@ public class FindCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find buy regions
|
||||
if(args[1].equalsIgnoreCase("buy")) {
|
||||
List<BuyRegion> regions = plugin.getFileManager().getBuys();
|
||||
List<BuyRegion> results = new ArrayList<>();
|
||||
for(BuyRegion region : regions) {
|
||||
if(!region.isSold()
|
||||
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
|
||||
&& (group == null || group.isMember(region))) {
|
||||
if(!region.isSold()
|
||||
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
|
||||
&& (group == null || group.isMember(region))
|
||||
&& (region.getBooleanSetting("general.findCrossWorld") || player.getWorld().equals(region.getWorld()))) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if(!results.isEmpty()) {
|
||||
// Draw a random one
|
||||
BuyRegion region = results.get(new Random().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.none();
|
||||
BuyRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
|
||||
// Teleport
|
||||
if(maxPriceSet) {
|
||||
plugin.message(player, "find-successMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup, region);
|
||||
} else {
|
||||
plugin.message(player, "find-success", "buy", Utils.formatCurrency(balance), onlyInGroup, region);
|
||||
}
|
||||
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
} else {
|
||||
Message onlyInGroup = Message.none();
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
@@ -106,31 +107,37 @@ public class FindCommand extends CommandAreaShop {
|
||||
plugin.message(player, "find-noneFound", "buy", Utils.formatCurrency(balance), onlyInGroup);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
// Find rental regions
|
||||
else {
|
||||
List<RentRegion> regions = plugin.getFileManager().getRents();
|
||||
List<RentRegion> results = new ArrayList<>();
|
||||
List<RentRegion> results = new ArrayList<>(regions.size());
|
||||
for(RentRegion region : regions) {
|
||||
if(!region.isRented()
|
||||
if(!region.isRented()
|
||||
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
|
||||
&& (group == null || group.isMember(region))) {
|
||||
&& (group == null || group.isMember(region))
|
||||
&& (region.getBooleanSetting("general.findCrossWorld") || player.getWorld().equals(region.getWorld()))) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if(!results.isEmpty()) {
|
||||
// Draw a random one
|
||||
RentRegion region = results.get(new Random().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.none();
|
||||
RentRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
|
||||
// Teleport
|
||||
if(maxPriceSet) {
|
||||
plugin.message(player, "find-successMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup, region);
|
||||
} else {
|
||||
plugin.message(player, "find-success", "rent", Utils.formatCurrency(balance), onlyInGroup, region);
|
||||
}
|
||||
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
} else {
|
||||
Message onlyInGroup = Message.none();
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
@@ -143,7 +150,7 @@ public class FindCommand extends CommandAreaShop {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -14,15 +13,11 @@ import java.util.TreeSet;
|
||||
|
||||
public class GroupaddCommand extends CommandAreaShop {
|
||||
|
||||
public GroupaddCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupadd";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupadd")) {
|
||||
@@ -36,11 +31,11 @@ public class GroupaddCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.groupadd")) {
|
||||
plugin.message(sender, "groupadd-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
plugin.message(sender, "groupadd-help");
|
||||
return;
|
||||
}
|
||||
}
|
||||
RegionGroup group = plugin.getFileManager().getGroup(args[1]);
|
||||
if(group == null) {
|
||||
group = new RegionGroup(plugin, args[1]);
|
||||
@@ -52,13 +47,13 @@ public class GroupaddCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
Selection selection = plugin.getWorldEdit().getSelection(player);
|
||||
WorldEditSelection selection = plugin.getWorldEditHandler().getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
plugin.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
|
||||
if(regions.size() == 0) {
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
@@ -71,10 +66,10 @@ public class GroupaddCommand extends CommandAreaShop {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if(regionsSuccess.size() != 0) {
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
plugin.message(player, "groupadd-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(regionsFailed.size() != 0) {
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
plugin.message(player, "groupadd-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
@@ -93,14 +88,14 @@ public class GroupaddCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = plugin.getFileManager().getGroupNames();
|
||||
} else if(toComplete == 3) {
|
||||
result = plugin.getFileManager().getRegionNames();
|
||||
result = plugin.getFileManager().getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -14,15 +13,11 @@ import java.util.TreeSet;
|
||||
|
||||
public class GroupdelCommand extends CommandAreaShop {
|
||||
|
||||
public GroupdelCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupdel";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupdel")) {
|
||||
@@ -36,29 +31,30 @@ public class GroupdelCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.groupdel")) {
|
||||
plugin.message(sender, "groupdel-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
plugin.message(sender, "groupdel-help");
|
||||
return;
|
||||
}
|
||||
}
|
||||
RegionGroup group = plugin.getFileManager().getGroup(args[1]);
|
||||
if(group == null) {
|
||||
group = new RegionGroup(plugin, args[1]);
|
||||
plugin.getFileManager().addGroup(group);
|
||||
plugin.message(sender, "groupdel-wrongGroup", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 2) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
Selection selection = plugin.getWorldEdit().getSelection(player);
|
||||
WorldEditSelection selection = plugin.getWorldEditHandler().getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
plugin.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
|
||||
if(regions.size() == 0) {
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
@@ -71,10 +67,10 @@ public class GroupdelCommand extends CommandAreaShop {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if(regionsSuccess.size() != 0) {
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
plugin.message(player, "groupdel-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(regionsFailed.size() != 0) {
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
plugin.message(player, "groupdel-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
@@ -85,7 +81,7 @@ public class GroupdelCommand extends CommandAreaShop {
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(group.removeMember(region)) {
|
||||
region.update();
|
||||
plugin.message(sender, "groupdel-success", group.getName(), group.getMembers().size(), region);
|
||||
@@ -94,12 +90,12 @@ public class GroupdelCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = plugin.getFileManager().getGroupNames();
|
||||
result = plugin.getFileManager().getGroupNames();
|
||||
} else if(toComplete == 3) {
|
||||
result = plugin.getFileManager().getRegionNames();
|
||||
}
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class GroupinfoCommand extends CommandAreaShop {
|
||||
|
||||
public GroupinfoCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupinfo";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupinfo")) {
|
||||
@@ -33,24 +29,24 @@ public class GroupinfoCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.groupinfo")) {
|
||||
plugin.message(sender, "groupinfo-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
plugin.message(sender, "groupinfo-help");
|
||||
return;
|
||||
}
|
||||
}
|
||||
RegionGroup group = plugin.getFileManager().getGroup(args[1]);
|
||||
if(group == null) {
|
||||
plugin.message(sender, "groupinfo-noGroup", args[1]);
|
||||
return;
|
||||
}
|
||||
List<String> members = group.getMembers();
|
||||
if(members.size() == 0) {
|
||||
Set<String> members = group.getMembers();
|
||||
if(members.isEmpty()) {
|
||||
plugin.message(sender, "groupinfo-noMembers", group.getName());
|
||||
} else {
|
||||
plugin.message(sender, "groupinfo-members", group.getName(), Utils.createCommaSeparatedList(members));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -9,15 +8,11 @@ import java.util.List;
|
||||
|
||||
public class GrouplistCommand extends CommandAreaShop {
|
||||
|
||||
public GrouplistCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop grouplist";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.grouplist")) {
|
||||
@@ -33,13 +28,13 @@ public class GrouplistCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
List<String> groups = plugin.getFileManager().getGroupNames();
|
||||
if(groups.size() == 0) {
|
||||
if(groups.isEmpty()) {
|
||||
plugin.message(sender, "grouplist-noGroups");
|
||||
} else {
|
||||
plugin.message(sender, "grouplist-success", Utils.createCommaSeparatedList(groups));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class HelpCommand extends CommandAreaShop {
|
||||
|
||||
public HelpCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop help";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.help")) {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ImportCommand extends CommandAreaShop {
|
||||
|
||||
/* RegionGroup priority usage:
|
||||
0: Settings from /config.yml
|
||||
1: Settings from /worlds/<world>/config.yml
|
||||
2: Settings from /worlds/<world>/parent-regions.yml (if their priority is set it is added to this value)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop import";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.import")) {
|
||||
return "help-import";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - Landlord?
|
||||
// - Friends
|
||||
// - Region flags?
|
||||
// - Settings from the 'permissions' section in RegionForSale/config.yml?
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.import")) {
|
||||
plugin.message(sender, "import-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 2) {
|
||||
plugin.message(sender, "import-help");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!"RegionForSale".equalsIgnoreCase(args[1])) {
|
||||
plugin.message(sender, "import-wrongSource");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!confirm(sender, args, Message.fromKey("import-confirm"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
new ImportJob(sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.add("RegionForSale");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,479 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ImportJob {
|
||||
|
||||
private final AreaShop plugin;
|
||||
private final CommandSender sender;
|
||||
|
||||
/**
|
||||
* Create and execute the import.
|
||||
* @param sender CommandSender that should receive progress updates
|
||||
*/
|
||||
public ImportJob(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
this.plugin = AreaShop.getInstance();
|
||||
execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
private void execute() {
|
||||
// Check for RegionForSale data
|
||||
File regionForSaleFolder = new File(plugin.getDataFolder().getParentFile().getAbsolutePath(), "RegionForSale");
|
||||
if(!regionForSaleFolder.exists()) {
|
||||
message("import-noPluginFolder", regionForSaleFolder.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
File worldsFolder = new File(regionForSaleFolder.getAbsolutePath(), "worlds");
|
||||
if(!worldsFolder.exists()) {
|
||||
message("import-noWorldsFolder");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] worldFolders = worldsFolder.listFiles();
|
||||
if(worldFolders == null) {
|
||||
message("import-noWorldsFolder");
|
||||
return;
|
||||
}
|
||||
|
||||
// Import data for each world
|
||||
message("import-start");
|
||||
|
||||
// Group with settings for all imported regions
|
||||
RegionGroup regionForSaleGroup = new RegionGroup(plugin, "RegionForSale");
|
||||
plugin.getFileManager().addGroup(regionForSaleGroup);
|
||||
|
||||
// Import /RegionForSale/config.yml settings
|
||||
File regionForSaleConfigFile = new File(regionForSaleFolder.getAbsolutePath(), "config.yml");
|
||||
YamlConfiguration regionForSaleConfig = loadConfiguration(regionForSaleConfigFile);
|
||||
if(regionForSaleConfig == null) {
|
||||
messageNoPrefix("import-loadConfigFailed", regionForSaleConfigFile.getAbsolutePath());
|
||||
regionForSaleConfig = new YamlConfiguration();
|
||||
} else {
|
||||
importRegionSettings(regionForSaleConfig, regionForSaleGroup.getSettings(), null, false);
|
||||
regionForSaleGroup.setSetting("priority", 0);
|
||||
}
|
||||
|
||||
// Import /RegionForSale/general.yml settings
|
||||
File regionForSaleGeneralFile = new File(regionForSaleFolder.getAbsolutePath(), "config.yml");
|
||||
YamlConfiguration regionForSaleGeneral = loadConfiguration(regionForSaleConfigFile);
|
||||
if(regionForSaleGeneral == null) {
|
||||
messageNoPrefix("import-loadConfigFailed", regionForSaleGeneralFile.getAbsolutePath());
|
||||
} else {
|
||||
// Collection interval of RegionForSale maps to rent duration
|
||||
String duration = "1 day";
|
||||
if(regionForSaleGeneral.isLong("interval.collect_money")) {
|
||||
duration = minutesToString(regionForSaleGeneral.getLong("interval.collect_money"));
|
||||
}
|
||||
regionForSaleGroup.setSetting("rent.duration", duration);
|
||||
|
||||
// Global economy account has an effect close to landlord in AreaShop
|
||||
if(regionForSaleGeneral.isString("global_econ_account")) {
|
||||
regionForSaleGroup.setSetting("general.landlordName", regionForSaleGeneral.getString("global_econ_account"));
|
||||
}
|
||||
}
|
||||
regionForSaleGroup.saveRequired();
|
||||
|
||||
////////// Handle defaults of RegionForSale
|
||||
|
||||
// Set autoExtend, to keep the same behavior as RegionForSale had
|
||||
regionForSaleGroup.setSetting("rent.autoExtend", true);
|
||||
|
||||
// Import regions from each world
|
||||
for(File worldFolder : worldFolders) {
|
||||
// Skip files
|
||||
if(!worldFolder.isDirectory() || worldFolder.isHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
messageNoPrefix("import-doWorld", worldFolder.getName());
|
||||
|
||||
// Get the Bukkit world
|
||||
World world = Bukkit.getWorld(worldFolder.getName());
|
||||
if(world == null) {
|
||||
messageNoPrefix("import-noBukkitWorld");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the WorldGuard RegionManager
|
||||
RegionManager regionManager = plugin.getRegionManager(world);
|
||||
if(regionManager == null) {
|
||||
messageNoPrefix("import-noRegionManger");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load the /worlds/<world>/regions.yml file
|
||||
File regionsFile = new File(worldFolder.getAbsolutePath(), "regions.yml");
|
||||
YamlConfiguration regions = loadConfiguration(regionsFile);
|
||||
if(regions == null) {
|
||||
messageNoPrefix("import-loadRegionsFailed", regionsFile.getAbsolutePath());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load /worlds/<world>/config.yml file
|
||||
File worldConfigFile = new File(worldFolder.getAbsolutePath(), "config.yml");
|
||||
YamlConfiguration worldConfig = loadConfiguration(worldConfigFile);
|
||||
if(worldConfig == null) {
|
||||
messageNoPrefix("import-loadWorldConfigFailed", worldConfigFile.getAbsolutePath());
|
||||
// Simply skip importing the settings, since this is not really fatal
|
||||
worldConfig = new YamlConfiguration();
|
||||
} else {
|
||||
// RegionGroup with all world settings
|
||||
RegionGroup worldGroup = new RegionGroup(plugin, "RegionForSale-" + worldFolder.getName());
|
||||
importRegionSettings(worldConfig, worldGroup.getSettings(), null, false);
|
||||
worldGroup.setSetting("priority", 1);
|
||||
worldGroup.addWorld(worldFolder.getName());
|
||||
plugin.getFileManager().addGroup(regionForSaleGroup);
|
||||
worldGroup.saveRequired();
|
||||
}
|
||||
|
||||
// Create groups to hold settings of /worlds/<world>/parent-regions.yml
|
||||
File parentRegionsFile = new File(worldFolder.getAbsolutePath(), "parent-regions.yml");
|
||||
YamlConfiguration parentRegions = loadConfiguration(parentRegionsFile);
|
||||
if(parentRegions == null) {
|
||||
messageNoPrefix("import-loadParentRegionsFailed", parentRegionsFile.getAbsolutePath());
|
||||
// Non-fatal, so just continue
|
||||
} else {
|
||||
for(String parentRegionName : parentRegions.getKeys(false)) {
|
||||
// Get WorldGuard region
|
||||
ProtectedRegion worldGuardRegion = regionManager.getRegion(parentRegionName);
|
||||
if(worldGuardRegion == null) {
|
||||
messageNoPrefix("import-noWorldGuardRegionParent", parentRegionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get settings section
|
||||
ConfigurationSection parentRegionSection = parentRegions.getConfigurationSection(parentRegionName);
|
||||
if(parentRegionSection == null) {
|
||||
messageNoPrefix("import-improperParentRegion", parentRegionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if it does not have any settings
|
||||
if(parentRegionSection.getKeys(false).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Import parent region settings into a RegionGroup
|
||||
RegionGroup parentRegionGroup = new RegionGroup(plugin, "RegionForSale-" + worldFolder.getName() + "-" + parentRegionName);
|
||||
importRegionSettings(parentRegionSection, parentRegionGroup.getSettings(), null, false);
|
||||
parentRegionGroup.setSetting("priority", 2 + parentRegionSection.getLong("info.priority", 0));
|
||||
parentRegionGroup.saveRequired();
|
||||
|
||||
// TODO add all regions that are contained in this parent region
|
||||
// Utils.getWorldEditRegionsInSelection()
|
||||
}
|
||||
}
|
||||
|
||||
// Read and import regions
|
||||
for(String regionKey : regions.getKeys(false)) {
|
||||
GeneralRegion existingRegion = plugin.getFileManager().getRegion(regionKey);
|
||||
if(existingRegion != null) {
|
||||
if(world.getName().equalsIgnoreCase(existingRegion.getWorldName())) {
|
||||
messageNoPrefix("import-alreadyAdded", regionKey);
|
||||
} else {
|
||||
messageNoPrefix("import-alreadyAddedOtherWorld", regionKey, existingRegion.getWorldName(), world.getName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigurationSection regionSection = regions.getConfigurationSection(regionKey);
|
||||
if(regionSection == null) {
|
||||
messageNoPrefix("import-invalidRegionSection", regionKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get WorldGuard region
|
||||
ProtectedRegion worldGuardRegion = regionManager.getRegion(regionKey);
|
||||
if(worldGuardRegion == null) {
|
||||
messageNoPrefix("import-noWorldGuardRegion", regionKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
String owner = regionSection.getString("info.owner", null);
|
||||
boolean isBought = regionSection.getBoolean("info.is-bought");
|
||||
// TODO: should also take into config settings of parent regions
|
||||
boolean rentable = regionSection.getBoolean("economic-settings.rentable", worldConfig.getBoolean("economic-settings.rentable", regionForSaleConfig.getBoolean("economic-settings.rentable")));
|
||||
boolean buyable = regionSection.getBoolean("economic-settings.buyable", worldConfig.getBoolean("economic-settings.buyable", regionForSaleConfig.getBoolean("economic-settings.buyable")));
|
||||
|
||||
// Can be bought and rented, import as buy
|
||||
if(buyable && rentable) {
|
||||
messageNoPrefix("import-buyAndRent", regionKey);
|
||||
}
|
||||
|
||||
// Cannot be bought or rented, skip
|
||||
if(!buyable && !rentable && owner == null) {
|
||||
messageNoPrefix("import-noBuyAndNoRent", regionKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create region
|
||||
GeneralRegion region;
|
||||
if(rentable || (owner != null && !isBought)) {
|
||||
region = new RentRegion(regionKey, world);
|
||||
} else {
|
||||
region = new BuyRegion(regionKey, world);
|
||||
}
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(region);
|
||||
if (event.isCancelled()) {
|
||||
messageNoPrefix("general-cancelled", event.getReason());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Import settings
|
||||
importRegionSettings(regionSection, region.getConfig(), region, !buyable && !rentable);
|
||||
region.getConfig().set("general.importedFrom", "RegionForSale");
|
||||
|
||||
// Get existing owners and members
|
||||
List<UUID> existing = new ArrayList<>();
|
||||
if(owner != null) {
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(owner);
|
||||
if(offlinePlayer.hasPlayedBefore()) {
|
||||
existing.add(offlinePlayer.getUniqueId());
|
||||
}
|
||||
}
|
||||
for(UUID uuid : plugin.getWorldGuardHandler().getOwners(worldGuardRegion).asUniqueIdList()) {
|
||||
if(!existing.contains(uuid)) {
|
||||
existing.add(uuid);
|
||||
}
|
||||
}
|
||||
for(UUID uuid : plugin.getWorldGuardHandler().getMembers(worldGuardRegion).asUniqueIdList()) {
|
||||
if(!existing.contains(uuid)) {
|
||||
existing.add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
// First owner (or if none, the first member) will be the renter/buyer
|
||||
if(!existing.isEmpty()) {
|
||||
region.setOwner(existing.remove(0));
|
||||
}
|
||||
// Add others as friends
|
||||
for(UUID friend : existing) {
|
||||
region.getFriendsFeature().addFriend(friend, null);
|
||||
}
|
||||
|
||||
region.saveRequired();
|
||||
|
||||
messageNoPrefix("import-imported", regionKey);
|
||||
}
|
||||
}
|
||||
|
||||
// Update all regions
|
||||
plugin.getFileManager().updateAllRegions(sender);
|
||||
// Write all imported regions and settings to disk
|
||||
plugin.getFileManager().saveRequiredFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a YamlConfiguration from disk using UTF-8 encoding.
|
||||
* @param from File to read the configuration from
|
||||
* @return YamlConfiguration if the file exists and got read wihout problems, otherwise null
|
||||
*/
|
||||
private YamlConfiguration loadConfiguration(File from) {
|
||||
try(
|
||||
InputStreamReader reader = new InputStreamReader(new FileInputStream(from), Charsets.UTF_8)
|
||||
) {
|
||||
return YamlConfiguration.loadConfiguration(reader);
|
||||
} catch(IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import region specific settings from a RegionForSale source to an AreaShop target ConfigurationSection.
|
||||
* @param from RegionForSale config section that specifies region settings
|
||||
* @param to AreaShop config section that specifies region settings
|
||||
* @param region GeneralRegion to copy settings to, or null if doing generic settings
|
||||
* @param permanent Region cannot be rented or bought, disables some features
|
||||
*/
|
||||
private void importRegionSettings(ConfigurationSection from, ConfigurationSection to, GeneralRegion region, boolean permanent) {
|
||||
// Maximum rental time, TODO check if this is actually the same
|
||||
if(from.isLong("permissions.max-rent-time")) {
|
||||
to.set("rent.maxRentTime", minutesToString(from.getLong("permissions.max-rent-time")));
|
||||
}
|
||||
|
||||
// Region rebuild
|
||||
if(from.getBoolean("region-rebuilding.auto-rebuild")) {
|
||||
to.set("general.enableRestore", true);
|
||||
}
|
||||
|
||||
// Get price settings
|
||||
String unit = from.getString("economic-settings.unit-type");
|
||||
String rentPrice = from.getString("economic-settings.cost-per-unit.rent");
|
||||
String buyPrice = from.getString("economic-settings.cost-per-unit.buy");
|
||||
String sellPrice = from.getString("economic-settings.cost-per-unit.selling-price");
|
||||
// TODO: There is no easy way to import this, setup eventCommandsProfile?
|
||||
// String taxes = from.getString("economic-settings.cost-per-unit.taxes");
|
||||
|
||||
// Determine unit and add that to the price
|
||||
String unitSuffix = "";
|
||||
if("m3".equalsIgnoreCase(unit)) {
|
||||
unitSuffix = "*%volume%";
|
||||
} else { // m2 or nothing (in case not set, we should actually look in parent files to correctly set this...)
|
||||
unitSuffix = "*(%volume%/%height%)"; // This is better than width*depth because of polygon regions
|
||||
}
|
||||
|
||||
// Apply settings
|
||||
if(rentPrice != null) {
|
||||
to.set("rent.price", rentPrice + unitSuffix);
|
||||
}
|
||||
if(buyPrice != null) {
|
||||
to.set("buy.price", buyPrice + unitSuffix);
|
||||
if(sellPrice != null) {
|
||||
try {
|
||||
double buyPriceAmount = Double.parseDouble(buyPrice);
|
||||
double sellPriceAmount = Double.parseDouble(sellPrice);
|
||||
to.set("buy.moneyBack", sellPriceAmount / buyPriceAmount * 100);
|
||||
} catch(NumberFormatException e) {
|
||||
// There is not always a region here for the message, should probably indicate something though
|
||||
message("import-moneyBackFailed", buyPrice, sellPrice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply permanent region settings
|
||||
if(permanent) {
|
||||
to.set("buy.resellDisabled", true);
|
||||
to.set("buy.sellDisabled", true);
|
||||
to.set("general.countForLimits", false);
|
||||
}
|
||||
|
||||
// Set rented until
|
||||
if(from.isLong("info.last-withdrawal")
|
||||
&& region instanceof RentRegion) {
|
||||
RentRegion rentRegion = (RentRegion)region;
|
||||
long lastWithdrawal = from.getLong("info.last-withdrawal");
|
||||
// Because the rental duration is already imported into the region and its parents this should be correct
|
||||
rentRegion.setRentedUntil(lastWithdrawal + rentRegion.getDuration());
|
||||
}
|
||||
|
||||
// Import signs (list of strings like "297, 71, -22")
|
||||
if(from.isList("info.signs") && region != null) {
|
||||
for(String signLocation : from.getStringList("info.signs")) {
|
||||
String[] locationParts = signLocation.split(", ");
|
||||
if(locationParts.length != 3) {
|
||||
message("import-invalidSignLocation", region.getName(), signLocation);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse the location
|
||||
Location location;
|
||||
try {
|
||||
location = new Location(region.getWorld(), Double.parseDouble(locationParts[0]), Double.parseDouble(locationParts[1]), Double.parseDouble(locationParts[2]));
|
||||
} catch(NumberFormatException e) {
|
||||
message("import-invalidSignLocation", region.getName(), signLocation);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this location is already added to a region
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(location);
|
||||
if(regionSign != null) {
|
||||
if(!regionSign.getRegion().equals(region)) {
|
||||
message("import-signAlreadyAdded", region.getName(), signLocation, regionSign.getRegion().getName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// SignType and Facing will be written when the sign is updated later
|
||||
region.getSignsFeature().addSign(location, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TimeUnit {
|
||||
public final long minutes;
|
||||
public final String identifier;
|
||||
|
||||
TimeUnit(long minutes, String identifier) {
|
||||
this.minutes = minutes;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<TimeUnit> timeUnitLookup = new ArrayList<TimeUnit>() {
|
||||
{
|
||||
add(new TimeUnit(60 * 24 * 30 * 12, "year"));
|
||||
add(new TimeUnit(60 * 24 * 30, "month"));
|
||||
add(new TimeUnit(60 * 24, "day"));
|
||||
add(new TimeUnit(60, "hour"));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert minutes to a human-readable string.
|
||||
* @param minutes Value to convert
|
||||
* @return String that represents the same length of time in a readable format, like "1 day", "5 minutes", "3 months"
|
||||
*/
|
||||
private String minutesToString(long minutes) {
|
||||
// If the specified number of minutes can map nicely to a higher unit, use that one
|
||||
String resultUnit = "minute";
|
||||
long resultValue = minutes;
|
||||
for(TimeUnit unit : timeUnitLookup) {
|
||||
long result = minutes / unit.minutes;
|
||||
if(resultValue * unit.minutes == minutes) {
|
||||
resultUnit = unit.identifier;
|
||||
resultValue = result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return resultValue + " " + resultUnit + (resultValue == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a target without a prefix.
|
||||
* @param key The key of the language string
|
||||
* @param replacements The replacements to insert in the message
|
||||
*/
|
||||
public void messageNoPrefix(String key, Object... replacements) {
|
||||
plugin.messageNoPrefix(sender, key, replacements);
|
||||
|
||||
if(!(sender instanceof ConsoleCommandSender)) {
|
||||
plugin.messageNoPrefix(Bukkit.getConsoleSender(), key, replacements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a target, prefixed by the default chat prefix.
|
||||
* @param key The key of the language string
|
||||
* @param replacements The replacements to insert in the message
|
||||
*/
|
||||
public void message(String key, Object... replacements) {
|
||||
plugin.message(sender, key, replacements);
|
||||
|
||||
if(!(sender instanceof ConsoleCommandSender)) {
|
||||
plugin.message(Bukkit.getConsoleSender(), key, replacements);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,21 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
// TODO fix '/as info' help message hitting replacement limit (improve depth tracking?)
|
||||
// TODO add info about autoExtend
|
||||
public class InfoCommand extends CommandAreaShop {
|
||||
|
||||
public InfoCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop info";
|
||||
@@ -33,17 +30,17 @@ public class InfoCommand extends CommandAreaShop {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a page of a list of regions
|
||||
* @param sender The CommandSender to send the messages to
|
||||
* @param regions The regions to display
|
||||
* Display a page of a list of regions.
|
||||
* @param sender The CommandSender to send the messages to
|
||||
* @param regions The regions to display
|
||||
* @param filterGroup The group to filter the regions by
|
||||
* @param keyHeader The header to print above the page
|
||||
* @param pageInput The page number, if any
|
||||
* @param baseCommand The command to execute for next/previous page
|
||||
* @param keyHeader The header to print above the page
|
||||
* @param pageInput The page number, if any
|
||||
* @param baseCommand The command to execute for next/previous page (/areashop will be added)
|
||||
*/
|
||||
private void showSortedPagedList(CommandSender sender, List<? extends GeneralRegion> regions, RegionGroup filterGroup, String keyHeader, String pageInput, String baseCommand) {
|
||||
int MAX_ITEMS = 20;
|
||||
int ITEMS_PER_PAGE = MAX_ITEMS-2;
|
||||
int maximumItems = 20;
|
||||
int itemsPerPage = maximumItems - 2;
|
||||
int page = 1;
|
||||
if(pageInput != null && Utils.isNumeric(pageInput)) {
|
||||
try {
|
||||
@@ -54,106 +51,99 @@ public class InfoCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
if(filterGroup != null) {
|
||||
for(Iterator<? extends GeneralRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(!filterGroup.isMember(it.next())) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
regions.removeIf(generalRegion -> !filterGroup.isMember(generalRegion));
|
||||
}
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "info-noRegions");
|
||||
} else {
|
||||
long start = Calendar.getInstance().getTimeInMillis();
|
||||
// First sort by type, then by name
|
||||
Collections.sort(regions, new Comparator<GeneralRegion>() {
|
||||
@Override
|
||||
public int compare(GeneralRegion one, GeneralRegion two) {
|
||||
int typeCompare = getTypeOrder(two).compareTo(getTypeOrder(one));
|
||||
if(typeCompare != 0) {
|
||||
return typeCompare;
|
||||
} else {
|
||||
return one.getName().compareTo(two.getName());
|
||||
}
|
||||
regions.sort((one, two) -> {
|
||||
int typeCompare = Integer.compare(getTypeOrder(two), getTypeOrder(one));
|
||||
if(typeCompare != 0) {
|
||||
return typeCompare;
|
||||
} else {
|
||||
return one.getName().compareTo(two.getName());
|
||||
}
|
||||
});
|
||||
// Header
|
||||
Message limitedToGroup = Message.none();
|
||||
Message limitedToGroup = Message.empty();
|
||||
if(filterGroup != null) {
|
||||
limitedToGroup = Message.fromKey("info-limitedToGroup").replacements(filterGroup.getName());
|
||||
}
|
||||
plugin.message(sender, keyHeader, limitedToGroup);
|
||||
// Page entries
|
||||
int totalPages = (int)Math.ceil(regions.size()/(double)ITEMS_PER_PAGE); // Clip page to correct boundaries, not much need to tell the user
|
||||
if(regions.size() == ITEMS_PER_PAGE+1) { // 19 total items is mapped to 1 page of 19
|
||||
ITEMS_PER_PAGE++;
|
||||
int totalPages = (int)Math.ceil(regions.size() / (double)itemsPerPage); // Clip page to correct boundaries, not much need to tell the user
|
||||
if(regions.size() == itemsPerPage + 1) { // 19 total items is mapped to 1 page of 19
|
||||
itemsPerPage++;
|
||||
totalPages = 1;
|
||||
}
|
||||
page = Math.max(1, Math.min(totalPages, page));
|
||||
int linesPrinted = 1; // header
|
||||
for(int i = (page-1)*ITEMS_PER_PAGE; i < page*ITEMS_PER_PAGE && i < regions.size(); i++) {
|
||||
for(int i = (page - 1) * itemsPerPage; i < page * itemsPerPage && i < regions.size(); i++) {
|
||||
String state;
|
||||
GeneralRegion region = regions.get(i);
|
||||
if(region.getType() == GeneralRegion.RegionType.RENT) {
|
||||
if(region.getOwner() == null) {
|
||||
if(region instanceof RentRegion) {
|
||||
if(region.isAvailable()) {
|
||||
state = "Forrent";
|
||||
} else {
|
||||
state = "Rented";
|
||||
}
|
||||
} else {
|
||||
if(region.getOwner() == null) {
|
||||
} else if (region instanceof BuyRegion){
|
||||
if(region.isAvailable()) {
|
||||
state = "Forsale";
|
||||
} else if(!((BuyRegion)region).isInResellingMode()) {
|
||||
state = "Sold";
|
||||
} else {
|
||||
state = "Reselling";
|
||||
}
|
||||
} else {
|
||||
state = region.getState().getValue();
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-entry"+state, region);
|
||||
plugin.messageNoPrefix(sender, "info-entry" + state, region);
|
||||
linesPrinted++;
|
||||
}
|
||||
Message footer = Message.none();
|
||||
Message footer = Message.empty();
|
||||
// Previous button
|
||||
if(page > 1) {
|
||||
footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand+" "+(page-1)));
|
||||
footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand + " " + (page - 1)));
|
||||
} else {
|
||||
footer.append(Message.fromKey("info-pageNoPrevious"));
|
||||
}
|
||||
// Page status
|
||||
if(totalPages > 1) {
|
||||
String pageString = ""+page;
|
||||
for(int i = pageString.length(); i < (totalPages+"").length(); i++) {
|
||||
pageString = "0"+pageString;
|
||||
StringBuilder pageString = new StringBuilder("" + page);
|
||||
for(int i = pageString.length(); i < (totalPages + "").length(); i++) {
|
||||
pageString.insert(0, "0");
|
||||
}
|
||||
footer.append(Message.fromKey("info-pageStatus").replacements(page, totalPages));
|
||||
if(page < totalPages) {
|
||||
footer.append(Message.fromKey("info-pageNext").replacements(baseCommand+" "+(page+1)));
|
||||
footer.append(Message.fromKey("info-pageNext").replacements(baseCommand + " " + (page + 1)));
|
||||
} else {
|
||||
footer.append(Message.fromKey("info-pageNoNext"));
|
||||
}
|
||||
// Fill up space if the page is not full (aligns header nicely)
|
||||
for(int i = linesPrinted; i < MAX_ITEMS-1; i++) {
|
||||
for(int i = linesPrinted; i < maximumItems - 1; i++) {
|
||||
sender.sendMessage(" ");
|
||||
}
|
||||
footer.send(sender);
|
||||
long end = Calendar.getInstance().getTimeInMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer to order by type, usable for Comparators
|
||||
* Get an integer to order by type, usable for Comparators.
|
||||
* @param region The region to get the order for
|
||||
* @return An integer for sorting by type
|
||||
*/
|
||||
private Integer getTypeOrder(GeneralRegion region) {
|
||||
private int getTypeOrder(GeneralRegion region) {
|
||||
if(region.getType() == GeneralRegion.RegionType.RENT) {
|
||||
if(region.getOwner() == null) {
|
||||
if(region.isAvailable()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
if(region.getOwner() == null) {
|
||||
if(region.isAvailable()) {
|
||||
return 3;
|
||||
} else if(!((BuyRegion)region).isInResellingMode()) {
|
||||
return 4;
|
||||
@@ -162,7 +152,7 @@ public class InfoCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.info")) {
|
||||
@@ -186,61 +176,41 @@ public class InfoCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// All regions
|
||||
if(args[1].equalsIgnoreCase("all")) {
|
||||
showSortedPagedList(sender, plugin.getFileManager().getRegions(), filterGroup, "info-allHeader", (args.length > 2 ? args[2] : null), "/areashop info all");
|
||||
showSortedPagedList(sender, plugin.getFileManager().getRegions(), filterGroup, "info-allHeader", (args.length > 2 ? args[2] : null), "info all");
|
||||
}
|
||||
|
||||
|
||||
// Rented regions
|
||||
else if(args[1].equalsIgnoreCase("rented")) {
|
||||
List<RentRegion> regions = plugin.getFileManager().getRents();
|
||||
for(Iterator<RentRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(!it.next().isRented()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-rentedHeader", (args.length > 2 ? args[2] : null), "/areashop info rented");
|
||||
regions.removeIf(RentRegion::isAvailable);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-rentedHeader", (args.length > 2 ? args[2] : null), "info rented");
|
||||
}
|
||||
// Forrent regions
|
||||
else if(args[1].equalsIgnoreCase("forrent")) {
|
||||
List<RentRegion> regions = plugin.getFileManager().getRents();
|
||||
for(Iterator<RentRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(it.next().isRented()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forrentHeader", (args.length > 2 ? args[2] : null), "/areashop info forrent");
|
||||
regions.removeIf(RentRegion::isRented);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forrentHeader", (args.length > 2 ? args[2] : null), "info forrent");
|
||||
}
|
||||
// Sold regions
|
||||
else if(args[1].equalsIgnoreCase("sold")) {
|
||||
List<BuyRegion> regions = plugin.getFileManager().getBuys();
|
||||
for(Iterator<BuyRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(!it.next().isSold()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-soldHeader", (args.length > 2 ? args[2] : null), "/areashop info sold");
|
||||
regions.removeIf(BuyRegion::isAvailable);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-soldHeader", (args.length > 2 ? args[2] : null), "info sold");
|
||||
}
|
||||
// Forsale regions
|
||||
else if(args[1].equalsIgnoreCase("forsale")) {
|
||||
List<BuyRegion> regions = plugin.getFileManager().getBuys();
|
||||
for(Iterator<BuyRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(it.next().isSold()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forsaleHeader", (args.length > 2 ? args[2] : null), "/areashop info forsale");
|
||||
regions.removeIf(BuyRegion::isSold);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forsaleHeader", (args.length > 2 ? args[2] : null), "info forsale");
|
||||
}
|
||||
// Reselling regions
|
||||
else if(args[1].equalsIgnoreCase("reselling")) {
|
||||
List<BuyRegion> regions = plugin.getFileManager().getBuys();
|
||||
for(Iterator<BuyRegion> it = regions.iterator(); it.hasNext(); ) {
|
||||
if(!it.next().isInResellingMode()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-resellingHeader", (args.length > 2 ? args[2] : null), "/areashop info reselling");
|
||||
regions.removeIf(region -> !region.isInResellingMode());
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-resellingHeader", (args.length > 2 ? args[2] : null), "info reselling");
|
||||
}
|
||||
|
||||
// List of regions without a group
|
||||
@@ -252,245 +222,216 @@ public class InfoCommand extends CommandAreaShop {
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "info-nogroupNone");
|
||||
} else {
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-nogroupHeader", (args.length > 2 ? args[2] : null), "/areashop info nogroup");
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-nogroupHeader", (args.length > 2 ? args[2] : null), "info nogroup");
|
||||
}
|
||||
}
|
||||
|
||||
// Region info
|
||||
else if(args[1].equalsIgnoreCase("region")) {
|
||||
if(args.length > 1) {
|
||||
RentRegion rent = null;
|
||||
BuyRegion buy = null;
|
||||
if(args.length > 2) {
|
||||
rent = plugin.getFileManager().getRent(args[2]);
|
||||
buy = plugin.getFileManager().getBuy(args[2]);
|
||||
} else {
|
||||
if (sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
if(regions.get(0).isRentRegion()) {
|
||||
rent = (RentRegion)regions.get(0);
|
||||
} else if(regions.get(0).isBuyRegion()) {
|
||||
buy = (BuyRegion)regions.get(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
RentRegion rent = null;
|
||||
BuyRegion buy = null;
|
||||
if(args.length > 2) {
|
||||
rent = plugin.getFileManager().getRent(args[2]);
|
||||
buy = plugin.getFileManager().getBuy(args[2]);
|
||||
} else {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
if(regions.get(0) instanceof RentRegion) {
|
||||
rent = (RentRegion)regions.get(0);
|
||||
} else if(regions.get(0) instanceof BuyRegion) {
|
||||
buy = (BuyRegion)regions.get(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(rent == null && buy == null) {
|
||||
plugin.message(sender, "info-regionNotExisting", args[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rent != null) {
|
||||
plugin.message(sender, "info-regionHeaderRent", rent);
|
||||
if(rent.isRented()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRented", rent);
|
||||
plugin.messageNoPrefix(sender, "info-regionExtending", rent);
|
||||
// Money back
|
||||
if(UnrentCommand.canUse(sender, rent)) {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackRentClick", rent);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackRent", rent);
|
||||
}
|
||||
// Friends
|
||||
if(!rent.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if(DelfriendCommand.canUse(sender, rent)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFriends", rent, Utils.combinedMessage(rent.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionCanBeRented", rent);
|
||||
}
|
||||
if(rent.getLandlordName() != null) {
|
||||
plugin.messageNoPrefix(sender, "info-regionLandlord", rent);
|
||||
}
|
||||
// Maximum extends
|
||||
if(rent.getMaxExtends() != -1) {
|
||||
if(rent.getMaxExtends() == 0) {
|
||||
plugin.messageNoPrefix(sender, "info-regionNoExtending", rent);
|
||||
} else if(rent.isRented()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionExtendsLeft", rent);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionMaxExtends", rent);
|
||||
}
|
||||
}
|
||||
|
||||
if(rent == null && buy == null) {
|
||||
plugin.message(sender, "info-regionNotExisting", args[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rent != null) {
|
||||
plugin.message(sender, "info-regionHeaderRent", rent);
|
||||
if(rent.isRented()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRented", rent);
|
||||
plugin.messageNoPrefix(sender, "info-regionExtending", rent);
|
||||
// Money back
|
||||
if(UnrentCommand.canUse(sender, rent)) {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackRentClick", rent);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackRent", rent);
|
||||
}
|
||||
// Friends
|
||||
if(!rent.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if(DelfriendCommand.canUse(sender, rent)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFriends", rent, Utils.combinedMessage(rent.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionCanBeRented", rent);
|
||||
}
|
||||
if(rent.getLandlordName() != null) {
|
||||
plugin.messageNoPrefix(sender, "info-regionLandlord", rent);
|
||||
}
|
||||
// Maximum extends
|
||||
if(rent.getMaxExtends() != -1) {
|
||||
if(rent.getMaxExtends() == 0) {
|
||||
plugin.messageNoPrefix(sender, "info-regionNoExtending", rent);
|
||||
} else if(rent.isRented()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionExtendsLeft", rent);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionMaxExtends", rent);
|
||||
}
|
||||
}
|
||||
if(rent.getMaxRentTime() != -1) {
|
||||
plugin.messageNoPrefix(sender, "info-regionMaxRentTime", rent);
|
||||
}
|
||||
if(rent.getInactiveTimeUntilUnrent() != -1) {
|
||||
plugin.messageNoPrefix(sender, "info-regionInactiveUnrent", rent);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, rent)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(rent));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, rent)) {
|
||||
if(foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(rent));
|
||||
}
|
||||
// If maxExtends is zero it does not make sense to show this message
|
||||
if(rent.getMaxRentTime() != -1 && rent.getMaxExtends() != 0) {
|
||||
plugin.messageNoPrefix(sender, "info-regionMaxRentTime", rent);
|
||||
}
|
||||
if(rent.getInactivityThresholdMillis() != -1) {
|
||||
plugin.messageNoPrefix(sender, "info-regionInactiveUnrent", rent);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, rent)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(rent));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, rent)) {
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
tp.append(", ");
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(Location location : rent.getSignsFeature().getSignLocations()) {
|
||||
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()).getPlain());
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(rent));
|
||||
}
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(Location location : rent.getSignsFeature().getSignLocations()) {
|
||||
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()).getPlain());
|
||||
}
|
||||
if(!signLocations.isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !rent.getGroupNames().isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(rent.getGroupNames()));
|
||||
}
|
||||
// Restoring
|
||||
if(rent.isRestoreEnabled()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringRent", rent);
|
||||
}
|
||||
// Restrictions
|
||||
if(!rent.isRented()) {
|
||||
if(rent.restrictedToRegion()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionRent", rent);
|
||||
} else if(rent.restrictedToWorld()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldRent", rent);
|
||||
}
|
||||
if(!signLocations.isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionSigns", signLocations.toArray());
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFooterRent", rent);
|
||||
} else if(buy != null) {
|
||||
plugin.message(sender, "info-regionHeaderBuy", buy);
|
||||
if(buy.isSold()) {
|
||||
if(buy.isInResellingMode()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionReselling", buy);
|
||||
plugin.messageNoPrefix(sender, "info-regionReselPrice", buy);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionBought", buy);
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !rent.getGroupNames().isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(rent.getGroupNames()));
|
||||
}
|
||||
// Restoring
|
||||
if(rent.isRestoreEnabled()) {
|
||||
if(sender.hasPermission("areashop.setrestore")) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringRent", rent, Message.fromKey("info-regionRestoringProfile").replacements(rent.getRestoreProfile()));
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringRent", rent, "");
|
||||
}
|
||||
}
|
||||
// Restrictions
|
||||
if(!rent.isRented()) {
|
||||
if(rent.restrictedToRegion()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionRent", rent);
|
||||
} else if(rent.restrictedToWorld()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldRent", rent);
|
||||
}
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFooterRent", rent);
|
||||
} else if(buy != null) {
|
||||
plugin.message(sender, "info-regionHeaderBuy", buy);
|
||||
if(buy.isSold()) {
|
||||
if(buy.isInResellingMode()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionReselling", buy);
|
||||
plugin.messageNoPrefix(sender, "info-regionReselPrice", buy);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionBought", buy);
|
||||
}
|
||||
// Money back
|
||||
if(SellCommand.canUse(sender, buy)) {
|
||||
// Money back
|
||||
if(!buy.getBooleanSetting("buy.sellDisabled")) {
|
||||
if (SellCommand.canUse(sender, buy)) {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackBuyClick", buy);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionMoneyBackBuy", buy);
|
||||
}
|
||||
// Friends
|
||||
if(!buy.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if(DelfriendCommand.canUse(sender, buy)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFriends", buy, Utils.combinedMessage(buy.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
// Friends
|
||||
if(!buy.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if(DelfriendCommand.canUse(sender, buy)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionCanBeBought", buy);
|
||||
plugin.messageNoPrefix(sender, "info-regionFriends", buy, Utils.combinedMessage(buy.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
if(buy.getLandlord() != null) {
|
||||
plugin.messageNoPrefix(sender, "info-regionLandlord", buy);
|
||||
}
|
||||
if(buy.getInactiveTimeUntilSell() != -1) {
|
||||
plugin.messageNoPrefix(sender, "info-regionInactiveSell", buy);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, buy)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(buy));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, buy)) {
|
||||
if(foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(buy));
|
||||
}
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(Location location : buy.getSignsFeature().getSignLocations()) {
|
||||
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()).getPlain());
|
||||
}
|
||||
if(!signLocations.isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionSigns", signLocations.toArray());
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !buy.getGroupNames().isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(buy.getGroupNames()));
|
||||
}
|
||||
// Restoring
|
||||
if(buy.isRestoreEnabled()) {
|
||||
if(sender.hasPermission("areashop.setrestore")) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringBuy", buy, Message.fromKey("info-regionRestoringProfile").replacements(buy.getRestoreProfile()));
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringBuy", buy, "");
|
||||
}
|
||||
}
|
||||
// Restrictions
|
||||
if(!buy.isSold()) {
|
||||
if(buy.restrictedToRegion()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionBuy", buy);
|
||||
} else if(buy.restrictedToWorld()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldBuy", buy);
|
||||
}
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFooterBuy", buy);
|
||||
} else {
|
||||
plugin.messageNoPrefix(sender, "info-regionCanBeBought", buy);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "info-regionHelp");
|
||||
if(buy.getLandlord() != null) {
|
||||
plugin.messageNoPrefix(sender, "info-regionLandlord", buy);
|
||||
}
|
||||
if(buy.getInactivityThresholdMillis() != -1) {
|
||||
plugin.messageNoPrefix(sender, "info-regionInactiveSell", buy);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, buy)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(buy));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, buy)) {
|
||||
if(foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(buy));
|
||||
}
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(Location location : buy.getSignsFeature().getSignLocations()) {
|
||||
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()).getPlain());
|
||||
}
|
||||
if(!signLocations.isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !buy.getGroupNames().isEmpty()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(buy.getGroupNames()));
|
||||
}
|
||||
// Restoring
|
||||
if(buy.isRestoreEnabled()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestoringBuy", buy);
|
||||
}
|
||||
// Restrictions
|
||||
if(!buy.isSold()) {
|
||||
if(buy.restrictedToRegion()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionBuy", buy);
|
||||
} else if(buy.restrictedToWorld()) {
|
||||
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldBuy", buy);
|
||||
}
|
||||
}
|
||||
plugin.messageNoPrefix(sender, "info-regionFooterBuy", buy);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "info-help");
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "info-help");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a comma-space separated list from a collection of strings
|
||||
* @param list The collection with strings
|
||||
* @return A comma-space separated list of the strings in the collection
|
||||
*/
|
||||
public String createCommaString(Collection<String> list) {
|
||||
String result = "";
|
||||
boolean first = true;
|
||||
for(String part : list) {
|
||||
if(first) {
|
||||
result += part;
|
||||
first = false;
|
||||
} else {
|
||||
result += ", " + part;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class LinksignsCommand extends CommandAreaShop {
|
||||
|
||||
public LinksignsCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop linksigns";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.linksigns")) {
|
||||
@@ -33,12 +30,12 @@ public class LinksignsCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.linksigns")) {
|
||||
plugin.message(sender, "linksigns-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Player player = (Player)sender;
|
||||
if(plugin.getSignlinkerManager().isInSignLinkMode(player)) {
|
||||
plugin.getSignlinkerManager().exitSignLinkMode(player);
|
||||
@@ -47,23 +44,23 @@ public class LinksignsCommand extends CommandAreaShop {
|
||||
String profile = null;
|
||||
if(args.length > 1) {
|
||||
profile = args[1];
|
||||
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
|
||||
if(!profiles.contains(profile)) {
|
||||
ArrayList<String> message = new ArrayList<>();
|
||||
for(String p : profiles) {
|
||||
if(!message.isEmpty()) {
|
||||
message.add(", ");
|
||||
ConfigurationSection signProfilesSection = plugin.getConfig().getConfigurationSection("signProfiles");
|
||||
if(signProfilesSection != null) {
|
||||
Set<String> profiles = signProfilesSection.getKeys(false);
|
||||
if(!profiles.contains(profile)) {
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for(String p : profiles) {
|
||||
Message.fromKey("addsign-profile").replacements(p).get().forEach(joiner::add);
|
||||
}
|
||||
message.addAll(Message.fromKey("addsign-profile").replacements(p).get());
|
||||
plugin.message(sender, "addsign-wrongProfile", joiner.toString());
|
||||
return;
|
||||
}
|
||||
plugin.message(sender, "addsign-wrongProfile", Message.fromList(message));
|
||||
return;
|
||||
}
|
||||
}
|
||||
plugin.getSignlinkerManager().enterSignLinkMode(player, profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MeCommand extends CommandAreaShop {
|
||||
|
||||
public MeCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop me";
|
||||
@@ -30,7 +28,7 @@ public class MeCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.me")) {
|
||||
@@ -73,7 +71,7 @@ public class MeCommand extends CommandAreaShop {
|
||||
// Get the regions the player is added as friend
|
||||
Set<GeneralRegion> friendRegions = new HashSet<>();
|
||||
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
|
||||
if(region.getFriendsFeature().getFriends() != null && region.getFriendsFeature().getFriends().contains(player.getUniqueId())) {
|
||||
if(region.getFriendsFeature().getFriends().contains(player.getUniqueId())) {
|
||||
friendRegions.add(region);
|
||||
}
|
||||
}
|
||||
@@ -106,8 +104,15 @@ public class MeCommand extends CommandAreaShop {
|
||||
}
|
||||
}
|
||||
|
||||
public static void show() {
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -13,10 +12,6 @@ import java.util.List;
|
||||
|
||||
public class MessageCommand extends CommandAreaShop {
|
||||
|
||||
public MessageCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop message";
|
||||
@@ -24,9 +19,7 @@ public class MessageCommand extends CommandAreaShop {
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.message")) {
|
||||
return "help-message";
|
||||
}
|
||||
// Internal command, no need to show in the help list
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -48,9 +41,9 @@ public class MessageCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] messageArgs = new String[args.length-2];
|
||||
System.arraycopy(args, 2, messageArgs, 0, args.length-2);
|
||||
String message = StringUtils.join(messageArgs);
|
||||
String[] messageArgs = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, messageArgs, 0, args.length - 2);
|
||||
String message = StringUtils.join(messageArgs, " ");
|
||||
|
||||
Message.fromString(message).send(player);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Commands
|
||||
|
||||
This module contains all AreaShop commands.
|
||||
|
||||
* `CommandAreaShop` is extended by all other classes, and implements some general functionality and defines which methods should be implemented.
|
||||
* Other classes implement specific sub-commands, supply their help messages and tab completion.
|
||||
* `CommandManager` class in the `managers` package handles incoming commands and dispatches them to the classes in this package.
|
||||
@@ -1,19 +1,14 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class ReloadCommand extends CommandAreaShop {
|
||||
|
||||
public ReloadCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop reload";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.reload")) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -11,10 +10,6 @@ import java.util.List;
|
||||
|
||||
public class RentCommand extends CommandAreaShop {
|
||||
|
||||
public RentCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop rent";
|
||||
@@ -27,38 +22,38 @@ public class RentCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.rent")) {
|
||||
plugin.message(sender, "rent-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
if(args.length > 1 && args[1] != null) {
|
||||
RentRegion rent = plugin.getFileManager().getRent(args[1]);
|
||||
if(rent == null) {
|
||||
plugin.message(sender, "rent-notRentable");
|
||||
plugin.message(sender, "rent-notRentable", args[1]);
|
||||
} else {
|
||||
rent.rent(player);
|
||||
}
|
||||
} else {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getApplicableRentRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
} else {
|
||||
regions.get(0).rent(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -11,10 +10,6 @@ import java.util.List;
|
||||
|
||||
public class ResellCommand extends CommandAreaShop {
|
||||
|
||||
public ResellCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop resell";
|
||||
@@ -27,14 +22,14 @@ public class ResellCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
|
||||
plugin.message(sender, "resell-noPermissionOther");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(args.length <= 1) {
|
||||
plugin.message(sender, "resell-help");
|
||||
return;
|
||||
@@ -46,15 +41,21 @@ public class ResellCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "resell-wrongPrice", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(price < 0) {
|
||||
plugin.message(sender, "resell-wrongPrice", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
BuyRegion buy;
|
||||
if(args.length <= 2) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -63,7 +64,7 @@ public class ResellCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buy = plugin.getFileManager().getBuy(args[2]);
|
||||
if(buy == null) {
|
||||
@@ -84,18 +85,24 @@ public class ResellCommand extends CommandAreaShop {
|
||||
buy.update();
|
||||
plugin.message(sender, "resell-success", buy);
|
||||
} else if(sender.hasPermission("areashop.resell") && sender instanceof Player) {
|
||||
if(buy.isOwner((Player)sender)) {
|
||||
buy.enableReselling(price);
|
||||
buy.update();
|
||||
plugin.message(sender, "resell-success", buy);
|
||||
} else {
|
||||
if(!buy.isTransactionHolder((Player)sender)) {
|
||||
plugin.message(sender, "resell-noPermissionOther", buy);
|
||||
return;
|
||||
}
|
||||
|
||||
if(buy.getBooleanSetting("buy.resellDisabled")) {
|
||||
plugin.message(sender, "resell-disabled", buy);
|
||||
return;
|
||||
}
|
||||
|
||||
buy.enableReselling(price);
|
||||
buy.update();
|
||||
plugin.message(sender, "resell-success", buy);
|
||||
} else {
|
||||
plugin.message(sender, "resell-noPermission", buy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -11,10 +12,6 @@ import java.util.List;
|
||||
|
||||
public class SchematiceventCommand extends CommandAreaShop {
|
||||
|
||||
public SchematiceventCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop schemevent";
|
||||
@@ -27,18 +24,18 @@ public class SchematiceventCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.schematicevents")) {
|
||||
plugin.message(sender, "schemevent-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(args.length < 3 || args[1] == null || args[2] == null) {
|
||||
plugin.message(sender, "schemevent-help");
|
||||
return;
|
||||
}
|
||||
}
|
||||
GeneralRegion region = plugin.getFileManager().getRegion(args[1]);
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[1]);
|
||||
@@ -53,7 +50,7 @@ public class SchematiceventCommand extends CommandAreaShop {
|
||||
try {
|
||||
event = GeneralRegion.RegionEvent.valueOf(args[2].toUpperCase());
|
||||
} catch(IllegalArgumentException e) {
|
||||
exception = true;
|
||||
exception = true;
|
||||
}
|
||||
// Check for a totally wrong event or a non matching event
|
||||
if(exception) {
|
||||
@@ -62,8 +59,8 @@ public class SchematiceventCommand extends CommandAreaShop {
|
||||
values.add(value.getValue().toLowerCase());
|
||||
}
|
||||
plugin.message(sender, "schemevent-wrongEvent", args[2], Utils.createCommaSeparatedList(values), region);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
region.handleSchematicEvent(event);
|
||||
region.update();
|
||||
plugin.message(sender, "schemevent-success", args[2], region);
|
||||
@@ -77,9 +74,9 @@ public class SchematiceventCommand extends CommandAreaShop {
|
||||
} else if(toComplete == 3) {
|
||||
GeneralRegion region = plugin.getFileManager().getRegion(start[2]);
|
||||
if(region != null) {
|
||||
if(region.isRentRegion()) {
|
||||
if(region instanceof RentRegion) {
|
||||
result.addAll(Arrays.asList("created", "deleted", "rented", "unrented"));
|
||||
} else if(region.isBuyRegion()) {
|
||||
} else if(region instanceof BuyRegion) {
|
||||
result.addAll(Arrays.asList("created", "deleted", "bought", "sold"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.TransactionalRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -12,90 +12,87 @@ import java.util.List;
|
||||
|
||||
public class SellCommand extends CommandAreaShop {
|
||||
|
||||
public SellCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop sell";
|
||||
}
|
||||
/**
|
||||
* Check if a person can sell the region.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can sell it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (person.hasPermission("areashop.sell")) {
|
||||
return true;
|
||||
}
|
||||
if (person instanceof Player && region instanceof TransactionalRegion) {
|
||||
Player player = (Player) person;
|
||||
return ((TransactionalRegion) region).isTransactionHolder(player) && person.hasPermission("areashop.sellown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.sell") || target.hasPermission("areashop.sellown")) {
|
||||
return "help-sell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop sell";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can sell the region
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can sell it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if(person.hasPermission("areashop.sell")) {
|
||||
return true;
|
||||
}
|
||||
if(person instanceof Player) {
|
||||
Player player = (Player)person;
|
||||
return region.isOwner(player) && person.hasPermission("areashop.sellown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
|
||||
plugin.message(sender, "sell-noPermission");
|
||||
return;
|
||||
}
|
||||
BuyRegion buy;
|
||||
if(args.length <= 1) {
|
||||
if (sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
buy = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
buy = plugin.getFileManager().getBuy(args[1]);
|
||||
}
|
||||
if(buy == null) {
|
||||
plugin.message(sender, "sell-notRegistered");
|
||||
return;
|
||||
}
|
||||
if(!buy.isSold()) {
|
||||
plugin.message(sender, "sell-notBought", buy);
|
||||
return;
|
||||
}
|
||||
buy.sell(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(BuyRegion region : plugin.getFileManager().getBuys()) {
|
||||
if(region.isSold()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if (target.hasPermission("areashop.sell") || target.hasPermission("areashop.sellown")) {
|
||||
return "help-sell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
|
||||
plugin.message(sender, "sell-noPermission");
|
||||
return;
|
||||
}
|
||||
BuyRegion buy;
|
||||
if (args.length <= 1) {
|
||||
if (sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
buy = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
buy = plugin.getFileManager().getBuy(args[1]);
|
||||
}
|
||||
if (buy == null) {
|
||||
plugin.message(sender, "sell-notRegistered");
|
||||
return;
|
||||
}
|
||||
if (!buy.isSold()) {
|
||||
plugin.message(sender, "sell-notBought", buy);
|
||||
return;
|
||||
}
|
||||
buy.sell(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if (toComplete == 2) {
|
||||
for (BuyRegion region : plugin.getFileManager().getBuys()) {
|
||||
if (region.isSold()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -11,15 +10,11 @@ import java.util.List;
|
||||
|
||||
public class SetdurationCommand extends CommandAreaShop {
|
||||
|
||||
public SetdurationCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setduration";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setduration")) {
|
||||
@@ -44,13 +39,13 @@ public class SetdurationCommand extends CommandAreaShop {
|
||||
}
|
||||
RentRegion rent;
|
||||
if(args.length <= regionArgument) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getApplicableRentRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -59,7 +54,7 @@ public class SetdurationCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rent = plugin.getFileManager().getRent(args[regionArgument]);
|
||||
}
|
||||
@@ -70,7 +65,7 @@ public class SetdurationCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.setduration") && !(sender instanceof Player && rent.isLandlord(((Player)sender).getUniqueId()))) {
|
||||
plugin.message(sender, "setduration-noLandlord", rent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
|
||||
rent.setDuration(null);
|
||||
rent.update();
|
||||
@@ -83,26 +78,26 @@ public class SetdurationCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "setduration-wrongAmount", args[1], rent);
|
||||
return;
|
||||
}
|
||||
if(!Utils.checkTimeFormat(args[1]+" "+args[2])) {
|
||||
plugin.message(sender, "setduration-wrongFormat", args[1]+" "+args[2], rent);
|
||||
if(!Utils.checkTimeFormat(args[1] + " " + args[2])) {
|
||||
plugin.message(sender, "setduration-wrongFormat", args[1] + " " + args[2], rent);
|
||||
return;
|
||||
}
|
||||
rent.setDuration(args[1]+" "+args[2]);
|
||||
}
|
||||
rent.setDuration(args[1] + " " + args[2]);
|
||||
rent.update();
|
||||
plugin.message(sender, "setduration-success", rent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = plugin.getFileManager().getRentNames();
|
||||
} else if(toComplete == 4) {
|
||||
if(toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("minutes"));
|
||||
result.addAll(plugin.getConfig().getStringList("hours"));
|
||||
result.addAll(plugin.getConfig().getStringList("days"));
|
||||
result.addAll(plugin.getConfig().getStringList("months"));
|
||||
result.addAll(plugin.getConfig().getStringList("years"));
|
||||
} else if(toComplete == 4) {
|
||||
result = plugin.getFileManager().getRentNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -13,15 +12,11 @@ import java.util.List;
|
||||
|
||||
public class SetlandlordCommand extends CommandAreaShop {
|
||||
|
||||
public SetlandlordCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setlandlord";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setlandlord")) {
|
||||
@@ -35,7 +30,7 @@ public class SetlandlordCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.setlandlord")) {
|
||||
plugin.message(sender, "setlandlord-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2) {
|
||||
plugin.message(sender, "setlandlord-help");
|
||||
return;
|
||||
@@ -44,13 +39,13 @@ public class SetlandlordCommand extends CommandAreaShop {
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
|
||||
GeneralRegion region;
|
||||
if(args.length < 3) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -59,14 +54,14 @@ public class SetlandlordCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
region = plugin.getFileManager().getRegion(args[2]);
|
||||
}
|
||||
}
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
String playerName = player.getName();
|
||||
if(playerName == null || playerName.isEmpty()) {
|
||||
playerName = args[1];
|
||||
@@ -75,7 +70,7 @@ public class SetlandlordCommand extends CommandAreaShop {
|
||||
region.update();
|
||||
plugin.message(sender, "setlandlord-success", playerName, region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.regions.TransactionalRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -17,10 +17,6 @@ import java.util.UUID;
|
||||
|
||||
public class SetownerCommand extends CommandAreaShop {
|
||||
|
||||
public SetownerCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setowner";
|
||||
@@ -33,7 +29,7 @@ public class SetownerCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
@@ -44,15 +40,15 @@ public class SetownerCommand extends CommandAreaShop {
|
||||
if(args.length < 2) {
|
||||
plugin.message(sender, "setowner-help");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length == 2) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -69,59 +65,54 @@ public class SetownerCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "setowner-notRegistered");
|
||||
return;
|
||||
}
|
||||
|
||||
if(region.isRentRegion() && !sender.hasPermission("areashop.setownerrent")) {
|
||||
|
||||
if(region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
|
||||
plugin.message(sender, "setowner-noPermissionRent", region);
|
||||
return;
|
||||
}
|
||||
if(region.isBuyRegion() && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
if(region instanceof BuyRegion && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
plugin.message(sender, "setowner-noPermissionBuy", region);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
UUID uuid = null;
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(player != null) {
|
||||
if(player.hasPlayedBefore()) {
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
if(uuid == null) {
|
||||
plugin.message(sender, "setowner-noPlayer", args[1], region);
|
||||
return;
|
||||
}
|
||||
|
||||
if(region.isRentRegion()) {
|
||||
}
|
||||
|
||||
if(region instanceof RentRegion) {
|
||||
RentRegion rent = (RentRegion)region;
|
||||
if(rent.isRenter(uuid)) {
|
||||
if(rent.isTransactionHolder(uuid)) {
|
||||
// extend
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(rent.getRentedUntil() + rent.getDuration());
|
||||
rent.setRentedUntil(calendar.getTimeInMillis());
|
||||
rent.setRenter(uuid);
|
||||
rent.update();
|
||||
rent.setRentedUntil(rent.getRentedUntil() + rent.getDuration());
|
||||
plugin.message(sender, "setowner-succesRentExtend", region);
|
||||
} else {
|
||||
// change
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
long current = calendar.getTimeInMillis();
|
||||
if(rent.isRented()) {
|
||||
current = rent.getRentedUntil();
|
||||
if(!rent.isRented()) {
|
||||
rent.setRentedUntil(System.currentTimeMillis() + rent.getDuration());
|
||||
}
|
||||
calendar.setTimeInMillis(current + rent.getDuration());
|
||||
rent.setRentedUntil(calendar.getTimeInMillis());
|
||||
rent.setRenter(uuid);
|
||||
rent.update();
|
||||
plugin.message(sender, "setowner-succesRent", region);
|
||||
}
|
||||
rent.setTransactionHolder(uuid);
|
||||
}
|
||||
if(region.isBuyRegion()) {
|
||||
if(region instanceof BuyRegion) {
|
||||
BuyRegion buy = (BuyRegion)region;
|
||||
buy.setBuyer(uuid);
|
||||
buy.update();
|
||||
buy.setTransactionHolder(uuid);
|
||||
plugin.message(sender, "setowner-succesBuy", region);
|
||||
}
|
||||
if (region instanceof TransactionalRegion) {
|
||||
region.getFriendsFeature().deleteFriend(((TransactionalRegion) region).getTransactionHolder(), null);
|
||||
}
|
||||
region.update();
|
||||
region.saveRequired();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -13,15 +12,11 @@ import java.util.List;
|
||||
|
||||
public class SetpriceCommand extends CommandAreaShop {
|
||||
|
||||
public SetpriceCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setprice";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setprice")) {
|
||||
@@ -35,20 +30,20 @@ public class SetpriceCommand extends CommandAreaShop {
|
||||
if(!sender.hasPermission("areashop.setprice") && (!sender.hasPermission("areashop.setprice.landlord") && sender instanceof Player)) {
|
||||
plugin.message(sender, "setprice-noPermission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
plugin.message(sender, "setprice-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if(args.length < 3) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -57,10 +52,10 @@ public class SetpriceCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
region = plugin.getFileManager().getRegion(args[2]);
|
||||
}
|
||||
}
|
||||
if(region == null) {
|
||||
plugin.message(sender, "setprice-notRegistered", args[2]);
|
||||
return;
|
||||
@@ -70,10 +65,10 @@ public class SetpriceCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
|
||||
if(region.isRentRegion()) {
|
||||
((RentRegion)region).removePrice();
|
||||
} else if(region.isBuyRegion()) {
|
||||
((BuyRegion)region).removePrice();
|
||||
if(region instanceof RentRegion) {
|
||||
((RentRegion)region).setPrice(0);
|
||||
} else if(region instanceof BuyRegion) {
|
||||
((BuyRegion)region).setPrice(0);
|
||||
}
|
||||
region.update();
|
||||
plugin.message(sender, "setprice-successRemoved", region);
|
||||
@@ -86,21 +81,21 @@ public class SetpriceCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "setprice-wrongPrice", args[1], region);
|
||||
return;
|
||||
}
|
||||
if(region.isRentRegion()) {
|
||||
if(region instanceof RentRegion) {
|
||||
((RentRegion)region).setPrice(price);
|
||||
plugin.message(sender, "setprice-successRent", region);
|
||||
} else if(region.isBuyRegion()) {
|
||||
} else if(region instanceof BuyRegion) {
|
||||
((BuyRegion)region).setPrice(price);
|
||||
plugin.message(sender, "setprice-successBuy", region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 3) {
|
||||
result = plugin.getFileManager().getRegionNames();
|
||||
result = plugin.getFileManager().getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@@ -9,15 +8,11 @@ import java.util.List;
|
||||
|
||||
public class SetrestoreCommand extends CommandAreaShop {
|
||||
|
||||
public SetrestoreCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setrestore";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setrestore")) {
|
||||
@@ -50,7 +45,7 @@ public class SetrestoreCommand extends CommandAreaShop {
|
||||
region.setRestoreSetting(value);
|
||||
String valueString = "general";
|
||||
if(value != null) {
|
||||
valueString = value+"";
|
||||
valueString = value + "";
|
||||
}
|
||||
if(args.length > 3) {
|
||||
region.setSchematicProfile(args[3]);
|
||||
@@ -60,7 +55,7 @@ public class SetrestoreCommand extends CommandAreaShop {
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -14,25 +13,21 @@ import java.util.List;
|
||||
|
||||
public class SetteleportCommand extends CommandAreaShop {
|
||||
|
||||
public SetteleportCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop settp";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
|
||||
if(target.hasPermission("areashop.setteleportall") || target.hasPermission("areashop.setteleport")) {
|
||||
return "help-setteleport";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can set the teleport location of the region
|
||||
* Check if a person can set the teleport location of the region.
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can set the teleport location, otherwise false
|
||||
@@ -52,7 +47,7 @@ public class SetteleportCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "setteleport-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
@@ -60,7 +55,7 @@ public class SetteleportCommand extends CommandAreaShop {
|
||||
GeneralRegion region;
|
||||
if(args.length < 2) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player)sender).getLocation());
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
@@ -75,12 +70,12 @@ public class SetteleportCommand extends CommandAreaShop {
|
||||
}
|
||||
|
||||
boolean owner;
|
||||
|
||||
|
||||
if(region == null) {
|
||||
plugin.message(player, "setteleport-noRentOrBuy", args[1]);
|
||||
return;
|
||||
}
|
||||
if(region.isRentRegion()) {
|
||||
if(region instanceof RentRegion) {
|
||||
owner = player.getUniqueId().equals(((RentRegion)region).getRenter());
|
||||
} else {
|
||||
owner = player.getUniqueId().equals(((BuyRegion)region).getBuyer());
|
||||
@@ -95,7 +90,7 @@ public class SetteleportCommand extends CommandAreaShop {
|
||||
|
||||
ProtectedRegion wgRegion = region.getRegion();
|
||||
if(args.length > 2 && args[2] != null && (args[2].equalsIgnoreCase("reset") || args[2].equalsIgnoreCase("yes") || args[2].equalsIgnoreCase("true"))) {
|
||||
region.setTeleport(null);
|
||||
region.getTeleportFeature().setTeleport(null);
|
||||
region.update();
|
||||
plugin.message(player, "setteleport-reset", region);
|
||||
return;
|
||||
@@ -104,11 +99,11 @@ public class SetteleportCommand extends CommandAreaShop {
|
||||
plugin.message(player, "setteleport-notInside", region);
|
||||
return;
|
||||
}
|
||||
region.setTeleport(player.getLocation());
|
||||
region.getTeleportFeature().setTeleport(player.getLocation());
|
||||
region.update();
|
||||
plugin.message(player, "setteleport-success", region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,36 +1,33 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StackCommand extends CommandAreaShop {
|
||||
|
||||
public StackCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop stack";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.stack")) {
|
||||
@@ -47,7 +44,7 @@ public class StackCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
// Only from ingame
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
@@ -82,11 +79,11 @@ public class StackCommand extends CommandAreaShop {
|
||||
return;
|
||||
}
|
||||
// Get WorldEdit selection
|
||||
final Selection selection = plugin.getWorldEdit().getSelection(player);
|
||||
final WorldEditSelection selection = plugin.getWorldEditHandler().getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
plugin.message(player, "stack-noSelection");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Get or create group
|
||||
RegionGroup group = null;
|
||||
if(args.length > 5) {
|
||||
@@ -98,112 +95,149 @@ public class StackCommand extends CommandAreaShop {
|
||||
}
|
||||
// Get facing of the player (must be clearly one of the four directions to make sure it is no mistake)
|
||||
BlockFace facing = Utils.yawToFacing(player.getLocation().getYaw());
|
||||
if(!(facing == BlockFace.NORTH || facing == BlockFace.EAST || facing == BlockFace.SOUTH || facing == BlockFace.WEST)) {
|
||||
if(player.getLocation().getPitch() > 45) {
|
||||
facing = BlockFace.DOWN;
|
||||
} else if(player.getLocation().getPitch() < -45) {
|
||||
facing = BlockFace.UP;
|
||||
}
|
||||
if(!(facing == BlockFace.NORTH || facing == BlockFace.EAST || facing == BlockFace.SOUTH || facing == BlockFace.WEST || facing == BlockFace.UP || facing == BlockFace.DOWN)) {
|
||||
plugin.message(player, "stack-unclearDirection", facing.toString().toLowerCase().replace('_', '-'));
|
||||
return;
|
||||
}
|
||||
final Location shift = new Location(selection.getWorld(), 0, 0, 0);
|
||||
Vector shift = new Vector(0, 0, 0);
|
||||
if(facing == BlockFace.SOUTH) {
|
||||
shift.setZ(-selection.getLength() - gap);
|
||||
shift = shift.setZ(-selection.getLength() - gap);
|
||||
} else if(facing == BlockFace.WEST) {
|
||||
shift.setX(selection.getWidth() + gap);
|
||||
shift = shift.setX(selection.getWidth() + gap);
|
||||
} else if(facing == BlockFace.NORTH) {
|
||||
shift.setZ(selection.getLength() + gap);
|
||||
shift = shift.setZ(selection.getLength() + gap);
|
||||
} else if(facing == BlockFace.EAST) {
|
||||
shift.setX(-selection.getWidth() - gap);
|
||||
shift = shift.setX(-selection.getWidth() - gap);
|
||||
} else if(facing == BlockFace.DOWN) {
|
||||
shift = shift.setY(-selection.getHeight() - gap);
|
||||
} else if(facing == BlockFace.UP) {
|
||||
shift = shift.setY(selection.getHeight() + gap);
|
||||
}
|
||||
AreaShop.debug(" calculated shift vector: " + shift + ", with facing=" + facing);
|
||||
// Create regions and add them to AreaShop
|
||||
final String namePrefix = args[3];
|
||||
final String nameTemplate = args[3];
|
||||
|
||||
|
||||
final int regionsPerTick = plugin.getConfig().getInt("adding.regionsPerTick");
|
||||
final boolean rentRegions = "rent".equalsIgnoreCase(args[4]);
|
||||
final int amount = tempAmount;
|
||||
final RegionGroup finalGroup = group;
|
||||
final Vector finalShift = shift;
|
||||
String type;
|
||||
if(rentRegions) {
|
||||
type = "rent";
|
||||
} else {
|
||||
type = "buy";
|
||||
}
|
||||
Message groupsMessage = Message.none();
|
||||
Message groupsMessage = Message.empty();
|
||||
if(group != null) {
|
||||
groupsMessage = Message.fromKey("stack-addToGroup").replacements(group.getName());
|
||||
}
|
||||
plugin.message(player, "stack-accepted", amount, type, gap, namePrefix, groupsMessage);
|
||||
plugin.message(player, "stack-addStart", amount, regionsPerTick*20);
|
||||
}
|
||||
plugin.message(player, "stack-accepted", amount, type, gap, nameTemplate, groupsMessage);
|
||||
plugin.message(player, "stack-addStart", amount, regionsPerTick * 20);
|
||||
|
||||
Location minimumLocation = selection.getMinimumLocation();
|
||||
Vector minimumVector = new Vector(minimumLocation.getX(), minimumLocation.getY(), minimumLocation.getZ());
|
||||
Location maximumLocation = selection.getMaximumLocation();
|
||||
Vector maximumVector = new Vector(maximumLocation.getX(), maximumLocation.getY(), maximumLocation.getZ());
|
||||
new BukkitRunnable() {
|
||||
private int current = 0;
|
||||
private RegionManager manager = AreaShop.getInstance().getWorldGuard().getRegionManager(selection.getWorld());
|
||||
private int current = -1;
|
||||
private final RegionManager manager = AreaShop.getInstance().getRegionManager(selection.getWorld());
|
||||
private int counter = 1;
|
||||
private int tooLow = 0;
|
||||
private int tooHigh = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i=0; i<regionsPerTick; i++) {
|
||||
for(int i = 0; i < regionsPerTick; i++) {
|
||||
current++;
|
||||
if(current < amount) {
|
||||
// Create the region name
|
||||
String counterName = counter+"";
|
||||
int minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
|
||||
while(counterName.length() < minimumLength) {
|
||||
counterName = "0"+counterName;
|
||||
}
|
||||
String regionName = namePrefix + counterName;
|
||||
String regionName = countToName(nameTemplate, counter);
|
||||
while(manager.getRegion(regionName) != null || AreaShop.getInstance().getFileManager().getRegion(regionName) != null) {
|
||||
counter++;
|
||||
counterName = counter+"";
|
||||
minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
|
||||
while(counterName.length() < minimumLength) {
|
||||
counterName = "0"+counterName;
|
||||
}
|
||||
regionName = namePrefix + counterName;
|
||||
regionName = countToName(nameTemplate, counter);
|
||||
}
|
||||
|
||||
// Add the region to WorldGuard (at startposition shifted by the number of this region times the blocks it should shift)
|
||||
ProtectedCuboidRegion region = new ProtectedCuboidRegion(regionName,
|
||||
new BlockVector(
|
||||
selection.getMinimumPoint().getBlockX() + shift.getBlockX()*current,
|
||||
selection.getMinimumPoint().getBlockY() + shift.getBlockY()*current,
|
||||
selection.getMinimumPoint().getBlockZ() + shift.getBlockZ()*current
|
||||
),
|
||||
new BlockVector(
|
||||
selection.getMaximumPoint().getBlockX() + shift.getBlockX()*current,
|
||||
selection.getMaximumPoint().getBlockY() + shift.getBlockY()*current,
|
||||
selection.getMaximumPoint().getBlockZ() + shift.getBlockZ()*current
|
||||
)
|
||||
);
|
||||
manager.addRegion(region);
|
||||
// Add the region to AreaShop
|
||||
if(rentRegions) {
|
||||
RentRegion rent = new RentRegion(plugin, region.getId(), selection.getWorld());
|
||||
if(finalGroup != null) {
|
||||
finalGroup.addMember(rent);
|
||||
}
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
plugin.getFileManager().addRent(rent);
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
rent.update();
|
||||
} else {
|
||||
BuyRegion buy = new BuyRegion(plugin, region.getId(), selection.getWorld());
|
||||
if(finalGroup != null) {
|
||||
finalGroup.addMember(buy);
|
||||
}
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
plugin.getFileManager().addBuy(buy);
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
buy.update();
|
||||
Vector minimum = minimumVector.clone().add(finalShift.clone().multiply(current));
|
||||
Vector maximum = maximumVector.clone().add(finalShift.clone().multiply(current));
|
||||
|
||||
// Check for out of bounds
|
||||
if(minimum.getBlockY() < 0) {
|
||||
tooLow++;
|
||||
continue;
|
||||
} else if(maximum.getBlockY() > 256) {
|
||||
tooHigh++;
|
||||
continue;
|
||||
}
|
||||
current++;
|
||||
}
|
||||
ProtectedCuboidRegion region = plugin.getWorldGuardHandler().createCuboidRegion(regionName, minimum,maximum);
|
||||
manager.addRegion(region);
|
||||
|
||||
// Add the region to AreaShop
|
||||
GeneralRegion newRegion;
|
||||
if(rentRegions) {
|
||||
newRegion = new RentRegion(regionName, selection.getWorld());
|
||||
|
||||
} else {
|
||||
newRegion = new BuyRegion(regionName, selection.getWorld());
|
||||
}
|
||||
|
||||
if(finalGroup != null) {
|
||||
finalGroup.addMember(newRegion);
|
||||
}
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(newRegion);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(player, "general-cancelled", event.getReason());
|
||||
continue;
|
||||
}
|
||||
newRegion.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
newRegion.update();
|
||||
}
|
||||
}
|
||||
if(current >= amount) {
|
||||
if(player.isOnline()) {
|
||||
plugin.message(player, "stack-addComplete");
|
||||
int added = amount - tooLow - tooHigh;
|
||||
Message wrong = Message.empty();
|
||||
if(tooHigh > 0) {
|
||||
wrong.append(Message.fromKey("stack-tooHigh").replacements(tooHigh));
|
||||
}
|
||||
if(tooLow > 0) {
|
||||
wrong.append(Message.fromKey("stack-tooLow").replacements(tooLow));
|
||||
}
|
||||
plugin.message(player, "stack-addComplete", added, wrong);
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build a name from a count, with the right length.
|
||||
* @param template Template to put the name in (# to put the count there, otherwise count is appended)
|
||||
* @param count Number to use
|
||||
* @return name with prepended 0's
|
||||
*/
|
||||
private String countToName(String template, int count) {
|
||||
StringBuilder counterName = new StringBuilder().append(count);
|
||||
int minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
|
||||
while(counterName.length() < minimumLength) {
|
||||
counterName.insert(0, "0");
|
||||
}
|
||||
|
||||
if(template.contains("#")) {
|
||||
return template.replace("#", counterName);
|
||||
} else {
|
||||
return template + counterName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -11,10 +10,6 @@ import java.util.List;
|
||||
|
||||
public class StopresellCommand extends CommandAreaShop {
|
||||
|
||||
public StopresellCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop stopresell";
|
||||
@@ -27,7 +22,7 @@ public class StopresellCommand extends CommandAreaShop {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
|
||||
@@ -37,13 +32,13 @@ public class StopresellCommand extends CommandAreaShop {
|
||||
|
||||
BuyRegion buy;
|
||||
if(args.length <= 1) {
|
||||
if (sender instanceof Player) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
@@ -52,7 +47,7 @@ public class StopresellCommand extends CommandAreaShop {
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buy = plugin.getFileManager().getBuy(args[1]);
|
||||
if(buy == null) {
|
||||
@@ -82,9 +77,9 @@ public class StopresellCommand extends CommandAreaShop {
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "stopresell-noPermission", buy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -10,15 +9,11 @@ import java.util.List;
|
||||
|
||||
public class TeleportCommand extends CommandAreaShop {
|
||||
|
||||
public TeleportCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop tp";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
|
||||
@@ -28,7 +23,7 @@ public class TeleportCommand extends CommandAreaShop {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can teleport to the region (assuming he is not teleporting to a sign)
|
||||
* Check if a person can teleport to the region (assuming he is not teleporting to a sign).
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can teleport to it, otherwise false
|
||||
@@ -40,19 +35,20 @@ public class TeleportCommand extends CommandAreaShop {
|
||||
Player player = (Player)person;
|
||||
return player.hasPermission("areashop.teleportall")
|
||||
|| region.isOwner(player) && player.hasPermission("areashop.teleport")
|
||||
|| region.isAvailable() && player.hasPermission("areashop.teleportavailable")
|
||||
|| region.getFriendsFeature().getFriends().contains(player.getUniqueId()) && player.hasPermission("areashop.teleportfriend");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
|
||||
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportavailable") && !sender.hasPermission("areashop.teleportavailablesign") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
|
||||
plugin.message(sender, "teleport-noPermission");
|
||||
return;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
if(!(sender instanceof Player)) {
|
||||
plugin.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(args.length <= 1 || args[1] == null) {
|
||||
plugin.message(sender, "teleport-help");
|
||||
return;
|
||||
@@ -63,14 +59,15 @@ public class TeleportCommand extends CommandAreaShop {
|
||||
plugin.message(player, "teleport-noRentOrBuy", args[1]);
|
||||
return;
|
||||
}
|
||||
if(args.length >= 3 && (args[2].equalsIgnoreCase("sign") || args[2].equalsIgnoreCase("yes") || args[2].equalsIgnoreCase("true"))) {
|
||||
region.teleportPlayer(player, true);
|
||||
} else {
|
||||
region.teleportPlayer(player, false);
|
||||
}
|
||||
|
||||
boolean toSign = args.length >= 3 && (
|
||||
args[2].equalsIgnoreCase("sign")
|
||||
|| args[2].equalsIgnoreCase("yes")
|
||||
|| args[2].equalsIgnoreCase("true")
|
||||
);
|
||||
region.getTeleportFeature().teleportPlayer(player, toSign, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TestCommand implements CommandExecutor {
|
||||
|
||||
private AreaShop areaShop = AreaShop.getInstance();
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
if (sender instanceof Player) {
|
||||
final Player player = (Player) sender;
|
||||
final Location location = player.getLocation();
|
||||
ApplicableRegionSet region = areaShop.getRegionManager(player.getWorld()).getApplicableRegions(BlockVector3.at(location.getX(), location.getY(), location.getZ()));
|
||||
for (ProtectedRegion r : region.getRegions()) {
|
||||
player.sendMessage(r.getId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.regions.TransactionalRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -12,90 +12,87 @@ import java.util.List;
|
||||
|
||||
public class UnrentCommand extends CommandAreaShop {
|
||||
|
||||
public UnrentCommand(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop unrent";
|
||||
}
|
||||
/**
|
||||
* Check if a person can unrent the region.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can unrent it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (person.hasPermission("areashop.unrent")) {
|
||||
return true;
|
||||
}
|
||||
if (person instanceof Player && region instanceof TransactionalRegion) {
|
||||
Player player = (Player) person;
|
||||
return ((TransactionalRegion) region).isTransactionHolder(player) && person.hasPermission("areashop.unrentown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.unrent") || target.hasPermission("areashop.unrentown")) {
|
||||
return "help-unrent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop unrent";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can unrent the region
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can unrent it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if(person.hasPermission("areashop.unrent")) {
|
||||
return true;
|
||||
}
|
||||
if(person instanceof Player) {
|
||||
Player player = (Player)person;
|
||||
return region.isOwner(player) && person.hasPermission("areashop.unrentown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if (target.hasPermission("areashop.unrent") || target.hasPermission("areashop.unrentown")) {
|
||||
return "help-unrent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
|
||||
plugin.message(sender, "unrent-noPermission");
|
||||
return;
|
||||
}
|
||||
RentRegion rent;
|
||||
if(args.length <= 1) {
|
||||
if (sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getApplicableRentRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
rent = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
rent = plugin.getFileManager().getRent(args[1]);
|
||||
}
|
||||
if(rent == null) {
|
||||
plugin.message(sender, "unrent-notRegistered");
|
||||
return;
|
||||
}
|
||||
if(!rent.isRented()) {
|
||||
plugin.message(sender, "unrent-notRented", rent);
|
||||
return;
|
||||
}
|
||||
rent.unRent(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(RentRegion region : plugin.getFileManager().getRents()) {
|
||||
if(region.isRented()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
|
||||
plugin.message(sender, "unrent-noPermission");
|
||||
return;
|
||||
}
|
||||
RentRegion rent;
|
||||
if (args.length <= 1) {
|
||||
if (sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player) sender).getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
rent = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
rent = plugin.getFileManager().getRent(args[1]);
|
||||
}
|
||||
if (rent == null) {
|
||||
plugin.message(sender, "unrent-notRegistered");
|
||||
return;
|
||||
}
|
||||
if (!rent.isRented()) {
|
||||
plugin.message(sender, "unrent-notRented", rent);
|
||||
return;
|
||||
}
|
||||
rent.unRent(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if (toComplete == 2) {
|
||||
for (RentRegion region : plugin.getFileManager().getRents()) {
|
||||
if (region.isRented()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-16
@@ -1,25 +1,16 @@
|
||||
package me.wiefferink.areashop.events;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
public class CancellableRegionEvent<T> extends RegionEvent<T> {
|
||||
|
||||
public class CancellableAreaShopEvent extends Event {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private String reason;
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public CancellableRegionEvent(T region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the event from happening
|
||||
* Cancel the event from happening.
|
||||
* @param reason The reason of cancelling, used for display to the user, should end with a dot
|
||||
*/
|
||||
public void cancel(String reason) {
|
||||
@@ -28,7 +19,7 @@ public class CancellableAreaShopEvent extends Event {
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the event continue, possible overwriting a cancel() call from another plugin
|
||||
* Let the event continue, possible overwriting a cancel() call from another plugin.
|
||||
*/
|
||||
public void allow() {
|
||||
this.cancelled = false;
|
||||
@@ -36,7 +27,7 @@ public class CancellableAreaShopEvent extends Event {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event has been cancelled
|
||||
* Check if the event has been cancelled.
|
||||
* @return true if the event has been cancelled, otherwise false
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
@@ -44,10 +35,11 @@ public class CancellableAreaShopEvent extends Event {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reason why this event is cancelled
|
||||
* Get the reason why this event is cancelled.
|
||||
* @return null if there is no reason or the event is not cancelled, otherwise a string
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package me.wiefferink.areashop.events;
|
||||
|
||||
public class NotifyRegionEvent<T> extends RegionEvent<T> {
|
||||
public NotifyRegionEvent(T region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Events
|
||||
|
||||
This package contains event classes that allow other plugins to listen to events about AreaShop regions.
|
||||
|
||||
* `RegionEvent` class represents a generic event.
|
||||
* `CancellableRegionEvent` represents an event that has a region and can be cancelled.
|
||||
* `NotifyRegionEvent` represents events that are to inform only, and cannot be cancelled anymore (an `CancellableRegionEvent` would be sent first).
|
||||
+15
-2
@@ -3,16 +3,29 @@ package me.wiefferink.areashop.events;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class NotifyAreaShopEvent extends Event {
|
||||
|
||||
public class RegionEvent<T> extends Event {
|
||||
protected T region;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public RegionEvent(T region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
// Required by Bukkit/Spigot
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region of this event.
|
||||
* @return The region the event is about
|
||||
*/
|
||||
public T getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class AddingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public AddingRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +1,31 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to buy a region.
|
||||
*/
|
||||
public class BuyingRegionEvent extends CancellableAreaShopEvent {
|
||||
public class BuyingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
private BuyRegion region;
|
||||
private Player player;
|
||||
private final OfflinePlayer player;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that is about to get bought
|
||||
* @param player The player that tries to buy the region
|
||||
*/
|
||||
public BuyingRegionEvent(BuyRegion region, Player player) {
|
||||
this.region = region;
|
||||
public BuyingRegionEvent(BuyRegion region, OfflinePlayer player) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that is about to be bought
|
||||
* @return the region that is about to be bought
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to buy the region
|
||||
* Get the player that is trying to buy the region.
|
||||
* @return The player that is trying to buy the region
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
public OfflinePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class DeletingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public DeletingRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +1,39 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to rent a region
|
||||
* Broadcasted when a player tries to rent a region.
|
||||
*/
|
||||
public class RentingRegionEvent extends CancellableAreaShopEvent {
|
||||
public class RentingRegionEvent extends CancellableRegionEvent<RentRegion> {
|
||||
|
||||
private RentRegion region;
|
||||
private Player player;
|
||||
private boolean extending;
|
||||
private final OfflinePlayer player;
|
||||
private final boolean extending;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that is about to be rented
|
||||
* @param player The player that tries to rent the region
|
||||
* @param extending true if the player is extending the rental of the region, otherwise false
|
||||
*/
|
||||
public RentingRegionEvent(RentRegion region, Player player, boolean extending) {
|
||||
this.region = region;
|
||||
public RentingRegionEvent(RentRegion region, OfflinePlayer player, boolean extending) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
this.extending = extending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that is about to be rented
|
||||
* @return the region that is about to be rented
|
||||
*/
|
||||
public RentRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to rent the region
|
||||
* Get the player that is trying to rent the region.
|
||||
* @return The player that is trying to rent the region
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
public OfflinePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is extending the region or renting it for the first time
|
||||
* Check if the player is extending the region or renting it for the first time.
|
||||
* @return true if the player tries to extend the region, false if he tries to rent it the first time
|
||||
*/
|
||||
public boolean isExtending() {
|
||||
|
||||
+10
-19
@@ -1,40 +1,31 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to resell a region
|
||||
* Broadcasted when a player tries to resell a region.
|
||||
*/
|
||||
public class ResellingRegionEvent extends CancellableAreaShopEvent {
|
||||
public class ResellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
private BuyRegion region;
|
||||
private Player player;
|
||||
private final OfflinePlayer player;
|
||||
|
||||
/**
|
||||
* Contructor
|
||||
* Contructor.
|
||||
* @param region The region that the player is trying to resell
|
||||
* @param player The player that is trying to buy this region from the current owner
|
||||
*/
|
||||
public ResellingRegionEvent(BuyRegion region, Player player) {
|
||||
this.region = region;
|
||||
public ResellingRegionEvent(BuyRegion region, OfflinePlayer player) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that is about to be bought
|
||||
* @return the region that is about to be bought
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to buy the region
|
||||
* Get the player that is trying to buy the region.
|
||||
* @return The player that is trying to buy the region
|
||||
*/
|
||||
public Player getBuyer() {
|
||||
public OfflinePlayer getBuyer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,18 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is about to get sold
|
||||
* Broadcasted when a region is about to get sold.
|
||||
*/
|
||||
public class SellingRegionEvent extends CancellableAreaShopEvent {
|
||||
|
||||
private BuyRegion region;
|
||||
public class SellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that is about to get sold
|
||||
*/
|
||||
public SellingRegionEvent(BuyRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that is about to be sold
|
||||
* @return the region that is about to be sold
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,18 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is about to be unrented
|
||||
* Broadcasted when a region is about to be unrented.
|
||||
*/
|
||||
public class UnrentingRegionEvent extends CancellableAreaShopEvent {
|
||||
|
||||
private RentRegion region;
|
||||
public class UnrentingRegionEvent extends CancellableRegionEvent<RentRegion> {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that is about to be unrented
|
||||
*/
|
||||
public UnrentingRegionEvent(RentRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that is about to be rented
|
||||
* @return the region that is about to be rented
|
||||
*/
|
||||
public RentRegion getRegion() {
|
||||
return region;
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
+10
-19
@@ -1,41 +1,32 @@
|
||||
package me.wiefferink.areashop.events.askandnotify;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Broadcasted when a friend is being added to a region
|
||||
* Broadcasted when a friend is being added to a region.
|
||||
*/
|
||||
public class AddFriendEvent extends CancellableAreaShopEvent {
|
||||
public class AddedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
private GeneralRegion region;
|
||||
private OfflinePlayer friend;
|
||||
private CommandSender by;
|
||||
private final OfflinePlayer friend;
|
||||
private final CommandSender by;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region the friend is getting added to
|
||||
* @param friend The friend that is about to be added
|
||||
* @param by The CommandSender that is adding the friend, or null if none
|
||||
*/
|
||||
public AddFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
this.region = region;
|
||||
public AddedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
super(region);
|
||||
this.friend = friend;
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region where the friend is getting added to
|
||||
* @return the region
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OfflinePlayer that is getting added as friend
|
||||
* Get the OfflinePlayer that is getting added as friend.
|
||||
* @return The friend that is getting added
|
||||
*/
|
||||
public OfflinePlayer getFriend() {
|
||||
@@ -43,7 +34,7 @@ public class AddFriendEvent extends CancellableAreaShopEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CommandSender that is adding the friend
|
||||
* Get the CommandSender that is adding the friend.
|
||||
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
|
||||
*/
|
||||
public CommandSender getBy() {
|
||||
+10
-19
@@ -1,41 +1,32 @@
|
||||
package me.wiefferink.areashop.events.askandnotify;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Broadcasted when a friend is being added to a region
|
||||
* Broadcasted when a friend is being added to a region.
|
||||
*/
|
||||
public class DeleteFriendEvent extends CancellableAreaShopEvent {
|
||||
public class DeletedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
private GeneralRegion region;
|
||||
private OfflinePlayer friend;
|
||||
private CommandSender by;
|
||||
private final OfflinePlayer friend;
|
||||
private final CommandSender by;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region the friend is getting added to
|
||||
* @param friend The friend that is about to be added
|
||||
* @param by The CommandSender that is adding the friend, or null if none
|
||||
*/
|
||||
public DeleteFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
this.region = region;
|
||||
public DeletedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
super(region);
|
||||
this.friend = friend;
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region where the friend is getting added to
|
||||
* @return the region
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OfflinePlayer that is getting added as friend
|
||||
* Get the OfflinePlayer that is getting added as friend.
|
||||
* @return The friend that is getting added
|
||||
*/
|
||||
public OfflinePlayer getFriend() {
|
||||
@@ -43,7 +34,7 @@ public class DeleteFriendEvent extends CancellableAreaShopEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CommandSender that is adding the friend
|
||||
* Get the CommandSender that is adding the friend.
|
||||
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
|
||||
*/
|
||||
public CommandSender getBy() {
|
||||
@@ -1,28 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class AddedRegionEvent extends NotifyAreaShopEvent {
|
||||
|
||||
private GeneralRegion region;
|
||||
public class AddedRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public AddedRegionEvent(GeneralRegion region) {
|
||||
this.region = region;
|
||||
super(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been added
|
||||
* @return the region that has been added
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been bought
|
||||
* Broadcasted when a region has been bought.
|
||||
*/
|
||||
public class BoughtRegionEvent extends NotifyAreaShopEvent {
|
||||
|
||||
private BuyRegion region;
|
||||
public class BoughtRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that has been bought
|
||||
*/
|
||||
public BoughtRegionEvent(BuyRegion region) {
|
||||
this.region = region;
|
||||
super(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been bought
|
||||
* @return the region that has been bought
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been removed from AreaShop.
|
||||
*/
|
||||
public class DeletedRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been removed
|
||||
*/
|
||||
public DeletedRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when the data of a region changes.
|
||||
* Should be used for updating displays that use region data.
|
||||
*/
|
||||
public class RegionUpdateEvent extends NotifyAreaShopEvent {
|
||||
|
||||
private GeneralRegion region;
|
||||
|
||||
/**
|
||||
* Contructor
|
||||
* @param region The region that has been updated
|
||||
*/
|
||||
public RegionUpdateEvent(GeneralRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* The region that has been updated
|
||||
* @return The GeneralRegion that has been updated
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been removed from AreaShop
|
||||
*/
|
||||
public class RemovedRegionEvent extends NotifyAreaShopEvent {
|
||||
|
||||
private GeneralRegion region;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param region The region that has been removed
|
||||
*/
|
||||
public RemovedRegionEvent(GeneralRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been removed
|
||||
* @return the region that has been removed
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,28 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been rented
|
||||
* Broadcasted when a region has been rented.
|
||||
*/
|
||||
public class RentedRegionEvent extends NotifyAreaShopEvent {
|
||||
public class RentedRegionEvent extends NotifyRegionEvent<RentRegion> {
|
||||
|
||||
private RentRegion region;
|
||||
private boolean extended;
|
||||
private final boolean extended;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that has been rented
|
||||
* @param extended true if the region has been extended, false if this is the first time buying the region
|
||||
*/
|
||||
public RentedRegionEvent(RentRegion region, boolean extended) {
|
||||
super(region);
|
||||
this.region = region;
|
||||
this.extended = extended;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been rented
|
||||
* @return the region that has been rented
|
||||
*/
|
||||
public RentRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region was extended or rented for the first time
|
||||
* Check if the region was extended or rented for the first time.
|
||||
* @return true if the region was extended, false when rented for the first time
|
||||
*/
|
||||
public boolean hasExtended() {
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been resold
|
||||
* Broadcasted when a region has been resold.
|
||||
*/
|
||||
public class ResoldRegionEvent extends NotifyAreaShopEvent {
|
||||
public class ResoldRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
private BuyRegion region;
|
||||
private UUID from;
|
||||
private final UUID from;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
* @param region The region that has been resold
|
||||
* @param from The player from who the region has been resold to the current owner
|
||||
*/
|
||||
public ResoldRegionEvent(BuyRegion region, UUID from) {
|
||||
this.region = region;
|
||||
super(region);
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been bought
|
||||
* @return the region that has been bought
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region has been bought from
|
||||
* Get the player that the region has been bought from.
|
||||
* @return The UUID of the player that the region has been bought from
|
||||
*/
|
||||
public UUID getFromPlayer() {
|
||||
|
||||
@@ -1,41 +1,32 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is sold
|
||||
* Broadcasted when a region is sold.
|
||||
*/
|
||||
public class SoldRegionEvent extends NotifyAreaShopEvent {
|
||||
public class SoldRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
private BuyRegion region;
|
||||
private UUID oldBuyer;
|
||||
private double refundedMoney;
|
||||
private final UUID oldBuyer;
|
||||
private final double refundedMoney;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param region The region that has been sold
|
||||
* @param oldBuyer The player for which the region has been sold
|
||||
* Constructor.
|
||||
* @param region The region that has been sold
|
||||
* @param oldBuyer The player for which the region has been sold
|
||||
* @param refundedMoney The amount of money that has been refunded
|
||||
*/
|
||||
public SoldRegionEvent(BuyRegion region, UUID oldBuyer, double refundedMoney) {
|
||||
this.region = region;
|
||||
super(region);
|
||||
this.oldBuyer = oldBuyer;
|
||||
this.refundedMoney = refundedMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been sold
|
||||
* @return the region that has been sold
|
||||
*/
|
||||
public BuyRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region is sold for
|
||||
* Get the player that the region is sold for.
|
||||
* @return The UUID of the player that the region is sold for
|
||||
*/
|
||||
public UUID getOldBuyer() {
|
||||
@@ -43,7 +34,7 @@ public class SoldRegionEvent extends NotifyAreaShopEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount that is paid back to the player
|
||||
* Get the amount that is paid back to the player.
|
||||
* @return The amount of money paid back to the player
|
||||
*/
|
||||
public double getRefundedMoney() {
|
||||
|
||||
+11
-20
@@ -1,41 +1,32 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyAreaShopEvent;
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been unrented
|
||||
* Broadcasted when a region has been unrented.
|
||||
*/
|
||||
public class UnrentedRegionEvent extends NotifyAreaShopEvent {
|
||||
public class UnrentedRegionEvent extends NotifyRegionEvent<RentRegion> {
|
||||
|
||||
private RentRegion region;
|
||||
private UUID oldRenter;
|
||||
private double refundedMoney;
|
||||
private final UUID oldRenter;
|
||||
private final double refundedMoney;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param region The region that has been unrented
|
||||
* @param oldRenter The player that rented the region before it was unrented
|
||||
* Constructor.
|
||||
* @param region The region that has been unrented
|
||||
* @param oldRenter The player that rented the region before it was unrented
|
||||
* @param refundedMoney The amount of money that has been refunded
|
||||
*/
|
||||
public UnrentedRegionEvent(RentRegion region, UUID oldRenter, double refundedMoney) {
|
||||
this.region = region;
|
||||
super(region);
|
||||
this.oldRenter = oldRenter;
|
||||
this.refundedMoney = refundedMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region that has been unrented
|
||||
* @return the region that has been unrented
|
||||
*/
|
||||
public RentRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region was unrented for
|
||||
* Get the player that the region was unrented for.
|
||||
* @return The UUID of the player that the region was unrented for
|
||||
*/
|
||||
public UUID getOldRenter() {
|
||||
@@ -43,7 +34,7 @@ public class UnrentedRegionEvent extends NotifyAreaShopEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount that is paid back to the player
|
||||
* Get the amount that is paid back to the player.
|
||||
* @return The amount of money paid back to the player
|
||||
*/
|
||||
public double getRefundedMoney() {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when the data of a region changes.
|
||||
* Should be used for updating displays that use region data.
|
||||
*/
|
||||
public class UpdateRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Contructor.
|
||||
* @param region The region that has been updated
|
||||
*/
|
||||
public UpdateRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.UnrentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.AddedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.DeletedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UnrentedRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandsFeature extends RegionFeature {
|
||||
|
||||
/**
|
||||
* Run command for a certain event.
|
||||
* @param region Region to execute the events for
|
||||
* @param event The event
|
||||
* @param before The 'before' or 'after' commands
|
||||
*/
|
||||
public void runEventCommands(GeneralRegion region, GeneralRegion.RegionEvent event, boolean before) {
|
||||
ConfigurationSection eventCommandProfileSection = region.getConfigurationSectionSetting("general.eventCommandProfile", "eventCommandProfiles");
|
||||
if(eventCommandProfileSection == null) {
|
||||
return;
|
||||
}
|
||||
List<String> commands = eventCommandProfileSection.getStringList(event.getValue() + "." + (before ? "before" : "after"));
|
||||
if(commands == null || commands.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
region.runCommands(Bukkit.getConsoleSender(), commands);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void addingRegion(AddingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.CREATED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedRegion(AddedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.CREATED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void deletingRegion(DeletingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.DELETED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void deletedRegion(DeletedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.DELETED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void rentingRegion(RentingRegionEvent event) {
|
||||
// Technically the rent can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), event.isExtending() ? GeneralRegion.RegionEvent.EXTENDED : GeneralRegion.RegionEvent.RENTED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void rentedRegion(RentedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), event.hasExtended() ? GeneralRegion.RegionEvent.EXTENDED : GeneralRegion.RegionEvent.RENTED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void buyingRegion(BuyingRegionEvent event) {
|
||||
// Technically the buy can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.BOUGHT, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void boughtRegion(BoughtRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.BOUGHT, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void resellingRegion(ResellingRegionEvent event) {
|
||||
// Technically the resell can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.RESELL, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void resoldRegion(ResoldRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.RESELL, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void sellingRegion(SellingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.SOLD, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void soldRegion(SoldRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.SOLD, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void unrentingRegion(UnrentingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.UNRENTED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void unrentedRegion(UnrentedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.UNRENTED, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,25 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.events.ask.*;
|
||||
import me.wiefferink.areashop.events.askandnotify.AddFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeleteFriendEvent;
|
||||
import me.wiefferink.areashop.events.notify.*;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.UnrentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.AddedFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeletedFriendEvent;
|
||||
import me.wiefferink.areashop.events.notify.AddedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.DeletedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UnrentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class DebugFeature extends Feature implements Listener {
|
||||
public class DebugFeature extends RegionFeature {
|
||||
|
||||
@EventHandler
|
||||
public void buyingRegion(BuyingRegionEvent event) {
|
||||
@@ -28,7 +38,7 @@ public class DebugFeature extends Feature implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void soldRegion(SoldRegionEvent event) {
|
||||
AreaShop.debug("SoldRegionEvent: "+Utils.toName(event.getOldBuyer())+" sold "+event.getRegion().getName());
|
||||
AreaShop.debug("SoldRegionEvent: " + Utils.toName(event.getOldBuyer()) + " sold " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -38,7 +48,7 @@ public class DebugFeature extends Feature implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void resoldRegion(ResoldRegionEvent event) {
|
||||
AreaShop.debug("ResoldRegionEvent: "+Utils.toName(event.getFromPlayer())+" resold "+event.getRegion().getName()+" to "+event.getRegion().getPlayerName());
|
||||
AreaShop.debug("ResoldRegionEvent: " + Utils.toName(event.getFromPlayer()) + " resold " + event.getRegion().getName() + " to " + event.getRegion().getPlayerName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -58,31 +68,31 @@ public class DebugFeature extends Feature implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void unrentedRegion(UnrentedRegionEvent event) {
|
||||
AreaShop.debug("UnrentedRegionEvent: "+Utils.toName(event.getOldRenter())+" unrented "+event.getRegion().getName());
|
||||
AreaShop.debug("UnrentedRegionEvent: " + Utils.toName(event.getOldRenter()) + " unrented " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(RegionUpdateEvent event) {
|
||||
//AreaShop.debug("RegionUpdateEvent: " + event.getRegion().getName() + " updated");
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
//AreaShop.debug("UpdateRegionEvent: " + event.getRegion().getName() + " updated");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedRegion(AddedRegionEvent event) {
|
||||
AreaShop.debug("AddedRegionEvent: "+event.getRegion().getName());
|
||||
AreaShop.debug("AddedRegionEvent: " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void removedRegion(RemovedRegionEvent event) {
|
||||
AreaShop.debug("RemovedRegionEvent: "+event.getRegion().getName());
|
||||
public void removedRegion(DeletedRegionEvent event) {
|
||||
AreaShop.debug("DeletedRegionEvent: " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedFriend(AddFriendEvent event) {
|
||||
AreaShop.debug("AddFriendEvent: region "+event.getRegion().getName()+", "+event.getFriend().getName()+" by "+(event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
public void addedFriend(AddedFriendEvent event) {
|
||||
AreaShop.debug("AddedFriendEvent: region " + event.getRegion().getName() + ", " + event.getFriend().getName() + " by " + (event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void deleteFriend(DeleteFriendEvent event) {
|
||||
AreaShop.debug("DeleteFriendEvent: region "+event.getRegion().getName()+", "+event.getFriend().getName()+" by "+(event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
public void deleteFriend(DeletedFriendEvent event) {
|
||||
AreaShop.debug("DeletedFriendEvent: region " + event.getRegion().getName() + ", " + event.getFriend().getName() + " by " + (event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
|
||||
public class Feature {
|
||||
AreaShop plugin = AreaShop.getInstance();
|
||||
}
|
||||
@@ -1,77 +1,78 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.events.askandnotify.AddFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeleteFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.AddedFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeletedFriendEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FriendsFeature extends Feature {
|
||||
|
||||
private GeneralRegion region;
|
||||
public class FriendsFeature extends RegionFeature {
|
||||
|
||||
public FriendsFeature(GeneralRegion region) {
|
||||
this.region = region;
|
||||
setRegion(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a friend to the region
|
||||
* Add a friend to the region.
|
||||
* @param player The UUID of the player to add
|
||||
* @param by The CommandSender that is adding the friend, or null
|
||||
* @return true if the friend has been added, false if adding a friend was cancelled by another plugin
|
||||
*/
|
||||
public boolean addFriend(UUID player, CommandSender by) {
|
||||
// Fire and check event
|
||||
AddFriendEvent event = new AddFriendEvent(region, Bukkit.getOfflinePlayer(player), by);
|
||||
AddedFriendEvent event = new AddedFriendEvent(getRegion(), Bukkit.getOfflinePlayer(player), by);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
plugin.message(by, "general-cancelled", event.getReason(), this);
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> friends = new HashSet<>(region.getConfig().getStringList("general.friends"));
|
||||
Set<String> friends = new HashSet<>(getRegion().getConfig().getStringList("general.friends"));
|
||||
friends.add(player.toString());
|
||||
List<String> list = new ArrayList<>(friends);
|
||||
region.setSetting("general.friends", list);
|
||||
getRegion().setSetting("general.friends", list);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a friend from the region
|
||||
* Delete a friend from the region.
|
||||
* @param player The UUID of the player to delete
|
||||
* @param by The CommandSender that is adding the friend, or null
|
||||
* @return true if the friend has been added, false if adding a friend was cancelled by another plugin
|
||||
*/
|
||||
public boolean deleteFriend(UUID player, CommandSender by) {
|
||||
// Fire and check event
|
||||
DeleteFriendEvent event = new DeleteFriendEvent(region, Bukkit.getOfflinePlayer(player), by);
|
||||
DeletedFriendEvent event = new DeletedFriendEvent(getRegion(), Bukkit.getOfflinePlayer(player), by);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
plugin.message(by, "general-cancelled", event.getReason(), this);
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> friends = new HashSet<>(region.getConfig().getStringList("general.friends"));
|
||||
List<String> friends = getRegion().getConfig().getStringList("general.friends");
|
||||
friends.remove(player.toString());
|
||||
List<String> list = new ArrayList<>(friends);
|
||||
if(list.isEmpty()) {
|
||||
region.setSetting("general.friends", null);
|
||||
if(friends.isEmpty()) {
|
||||
getRegion().setSetting("general.friends", null);
|
||||
} else {
|
||||
region.setSetting("general.friends", list);
|
||||
getRegion().setSetting("general.friends", friends);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of friends added to this region
|
||||
* Get the list of friends added to this region.
|
||||
* @return Friends added to this region
|
||||
*/
|
||||
public Set<UUID> getFriends() {
|
||||
HashSet<UUID> result = new HashSet<>();
|
||||
for(String friend : region.getConfig().getStringList("general.friends")) {
|
||||
for(String friend : getRegion().getConfig().getStringList("general.friends")) {
|
||||
try {
|
||||
UUID id = UUID.fromString(friend);
|
||||
result.add(id);
|
||||
@@ -83,14 +84,14 @@ public class FriendsFeature extends Feature {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of friends added to this region
|
||||
* Get the list of friends added to this region.
|
||||
* @return Friends added to this region
|
||||
*/
|
||||
public Set<String> getFriendNames() {
|
||||
HashSet<String> result = new HashSet<>();
|
||||
for(UUID friend : getFriends()) {
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(friend);
|
||||
if(player != null) {
|
||||
if(player != null && player.getName() != null) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
}
|
||||
@@ -98,10 +99,10 @@ public class FriendsFeature extends Feature {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all friends that are added to this region
|
||||
* Remove all friends that are added to this region.
|
||||
*/
|
||||
public void clearFriends() {
|
||||
region.setSetting("general.friends", null);
|
||||
getRegion().setSetting("general.friends", null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Features
|
||||
|
||||
This package contains classes that represent a certain feature and implement it for all regions.
|
||||
|
||||
* `RegionFeature` represents a single feature, for each implementing class one instance is created without an assigned region, to listen for events etc, and an instance per region is created on-demand to handle region specific things.
|
||||
* More features will be moved from `GeneralRegion` to these kind of classes, to keep all code for a feature together and cleanup `GeneralRegion`.
|
||||
@@ -0,0 +1,73 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
/*
|
||||
Possible future feature classes:
|
||||
- RestrictedToRegion feature
|
||||
- rent/buy restricted to the region itself
|
||||
- RestrictedToWorld feature
|
||||
- rent/buy restricted to the world of the region
|
||||
- CountLimitsFeature:
|
||||
- Check region limits
|
||||
- TimeLimitsFeatures:
|
||||
- maxExtends
|
||||
- maxRentTime
|
||||
- SchematicFeature
|
||||
- save/load schematics
|
||||
- CommandsFeature
|
||||
- execute commands after extend/rent/etc
|
||||
- LandlordFeature
|
||||
- manage landlords
|
||||
- ExpirationWarningsFeature
|
||||
- sending rental expiration warnings
|
||||
*/
|
||||
|
||||
public abstract class RegionFeature implements Listener {
|
||||
public static final AreaShop plugin = AreaShop.getInstance();
|
||||
|
||||
protected YamlConfiguration config = plugin.getConfig();
|
||||
private GeneralRegion region;
|
||||
|
||||
/**
|
||||
* Set the region for this feature.
|
||||
* @param region Feature region
|
||||
*/
|
||||
public void setRegion(GeneralRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region of this feature.
|
||||
* @return region of this feature, or null if generic
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start listening to events.
|
||||
*/
|
||||
public void listen() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the feature and deregister everything.
|
||||
*/
|
||||
public void shutdownFeature() {
|
||||
HandlerList.unregisterAll(this);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy method a RegionFeature implementation can override.
|
||||
*/
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,346 +0,0 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.events.notify.RegionUpdateEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SignsFeature extends Feature implements Listener {
|
||||
|
||||
private static Map<String, RegionSign> allSigns = new HashMap<>();
|
||||
|
||||
private GeneralRegion region;
|
||||
private Map<String, RegionSign> signs;
|
||||
|
||||
public SignsFeature() {
|
||||
|
||||
}
|
||||
|
||||
public SignsFeature(GeneralRegion region) {
|
||||
this.region = region;
|
||||
signs = new HashMap<>();
|
||||
// Setup current signs
|
||||
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
|
||||
if(signSection != null) {
|
||||
for(String signKey : signSection.getKeys(false)) {
|
||||
RegionSign sign = new RegionSign(region, this, signKey);
|
||||
Location location = sign.getLocation();
|
||||
if(location == null) {
|
||||
AreaShop.warn("Sign with key "+signKey+" of region "+region.getName()+" does not have a proper location");
|
||||
continue;
|
||||
}
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
}
|
||||
allSigns.putAll(signs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a location to a string to use as map key
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a location
|
||||
*/
|
||||
public static String locationToString(Location location) {
|
||||
return location.getWorld().getName()+";"+location.getBlockX()+";"+location.getBlockY()+";"+location.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sign by a location
|
||||
* @param location The location to get the sign for
|
||||
* @return The RegionSign that is at the location, or null if none
|
||||
*/
|
||||
public static RegionSign getSignByLocation(Location location) {
|
||||
return allSigns.get(locationToString(location));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(RegionUpdateEvent event) {
|
||||
event.getRegion().getSignsFeature().update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all signs connected to this region
|
||||
* @return true if all signs are updated correctly, false if one or more updates failed
|
||||
*/
|
||||
public boolean update() {
|
||||
boolean result = true;
|
||||
for(RegionSign sign : signs.values()) {
|
||||
result = result&sign.update();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the signs need periodic updating
|
||||
* @return true if one or more of the signs need periodic updating, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
boolean result = false;
|
||||
for(RegionSign sign : signs.values()) {
|
||||
result = result|sign.needsPeriodicUpdate();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list with all sign locations
|
||||
* @return A List with all sign locations
|
||||
*/
|
||||
public List<Location> getSignLocations() {
|
||||
List<Location> result = new ArrayList<>();
|
||||
for(RegionSign sign : signs.values()) {
|
||||
result.add(sign.getLocation());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sign to this region
|
||||
* @param location The location of the sign
|
||||
* @param signType The type of the sign (WALL_SIGN or SIGN_POST)
|
||||
* @param facing The orientation of the sign
|
||||
* @param profile The profile to use with this sign (null for default)
|
||||
*/
|
||||
public void addSign(Location location, Material signType, BlockFace facing, String profile) {
|
||||
int i = 0;
|
||||
while(region.getConfig().isSet("general.signs."+i)) {
|
||||
i++;
|
||||
}
|
||||
String signPath = "general.signs."+i+".";
|
||||
region.setSetting(signPath+"location", Utils.locationToConfig(location));
|
||||
region.setSetting(signPath+"facing", facing.name());
|
||||
region.setSetting(signPath+"signType", signType.name());
|
||||
if(profile != null && profile.length() != 0) {
|
||||
region.setSetting(signPath+"profile", profile);
|
||||
}
|
||||
// Add to the map
|
||||
RegionSign sign = new RegionSign(region, this, i+"");
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
allSigns.put(sign.getStringLocation(), sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a sign from this region at the specified location
|
||||
* @param location Location to check
|
||||
* @return true if this region has a sign at the location, otherwise false
|
||||
*/
|
||||
public boolean isSignOfRegion(Location location) {
|
||||
Set<String> signs;
|
||||
if(region.getConfig().getConfigurationSection("general.signs") == null) {
|
||||
return false;
|
||||
}
|
||||
signs = region.getConfig().getConfigurationSection("general.signs").getKeys(false);
|
||||
for(String sign : signs) {
|
||||
Location signLocation = Utils.configToLocation(region.getConfig().getConfigurationSection("general.signs."+sign+".location"));
|
||||
if(signLocation != null
|
||||
&& signLocation.getWorld().equals(location.getWorld())
|
||||
&& signLocation.getBlockX() == location.getBlockX()
|
||||
&& signLocation.getBlockY() == location.getBlockY()
|
||||
&& signLocation.getBlockZ() == location.getBlockZ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sign that is connected to a region to display information and interact with the region
|
||||
*/
|
||||
public class RegionSign {
|
||||
|
||||
private GeneralRegion region;
|
||||
private SignsFeature signsFeature;
|
||||
private String key;
|
||||
|
||||
public RegionSign(GeneralRegion region, SignsFeature signsFeature, String key) {
|
||||
this.region = region;
|
||||
this.signsFeature = signsFeature;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of this sign
|
||||
* @return The location of this sign
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return Utils.configToLocation(region.getConfig().getConfigurationSection("general.signs."+key+".location"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Location string to be used as key in maps
|
||||
* @return Location string
|
||||
*/
|
||||
public String getStringLocation() {
|
||||
return locationToString(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region this sign is linked to
|
||||
* @return The region this sign is linked to
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this sign from the region
|
||||
*/
|
||||
public void remove() {
|
||||
getLocation().getBlock().setType(Material.AIR);
|
||||
signs.remove(getStringLocation());
|
||||
allSigns.remove(getStringLocation());
|
||||
region.setSetting("general.signs."+key, null);
|
||||
}
|
||||
|
||||
public String getProfile() {
|
||||
String profile = region.getConfig().getString("general.signs."+key+".profile");
|
||||
if(profile == null || profile.length() == 0) {
|
||||
profile = region.getStringSetting("general.signProfile");
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this sign
|
||||
* @return true if the update was successful, otherwise false
|
||||
*/
|
||||
public boolean update() {
|
||||
if(region.isDeleted()) {
|
||||
return false;
|
||||
}
|
||||
YamlConfiguration config = region.getConfig();
|
||||
// Get the prefix
|
||||
String prefix = "signProfiles."+getProfile()+"."+region.getState().getValue().toLowerCase()+".";
|
||||
// Get the lines
|
||||
String[] signLines = new String[4];
|
||||
signLines[0] = plugin.getConfig().getString(prefix+"line1");
|
||||
signLines[1] = plugin.getConfig().getString(prefix+"line2");
|
||||
signLines[2] = plugin.getConfig().getString(prefix+"line3");
|
||||
signLines[3] = plugin.getConfig().getString(prefix+"line4");
|
||||
// Check if the sign should be present
|
||||
Block block = getLocation().getBlock();
|
||||
if(!plugin.getConfig().isSet(prefix)
|
||||
|| ((signLines[0] == null || signLines[0].length() == 0)
|
||||
&& (signLines[1] == null || signLines[1].length() == 0)
|
||||
&& (signLines[2] == null || signLines[2].length() == 0)
|
||||
&& (signLines[3] == null || signLines[3].length() == 0))) {
|
||||
block.setType(Material.AIR);
|
||||
} else {
|
||||
Sign signState = null;
|
||||
if(block.getType() != Material.WALL_SIGN && block.getType() != Material.SIGN_POST) {
|
||||
Material signType;
|
||||
try {
|
||||
signType = Material.valueOf(config.getString("general.signs."+key+".signType"));
|
||||
} catch(NullPointerException|IllegalArgumentException e) {
|
||||
signType = null;
|
||||
}
|
||||
if(signType != Material.WALL_SIGN && signType != Material.SIGN_POST) {
|
||||
AreaShop.debug(" setting sign failed");
|
||||
return false;
|
||||
}
|
||||
block.setType(signType);
|
||||
signState = (Sign)block.getState();
|
||||
org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData();
|
||||
BlockFace signFace;
|
||||
try {
|
||||
signFace = BlockFace.valueOf(config.getString("general.signs."+key+".facing"));
|
||||
} catch(NullPointerException|IllegalArgumentException e) {
|
||||
signFace = null;
|
||||
}
|
||||
if(signFace != null) {
|
||||
signData.setFacingDirection(signFace);
|
||||
signState.setData(signData);
|
||||
}
|
||||
}
|
||||
if(signState == null) {
|
||||
signState = (Sign)block.getState();
|
||||
}
|
||||
org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData();
|
||||
if(!config.isString("general.signs."+key+".signType")) {
|
||||
region.setSetting("general.signs."+key+".signType", signState.getType().toString());
|
||||
}
|
||||
if(!config.isString("general.signs."+key+".facing")) {
|
||||
region.setSetting("general.signs."+key+".facing", signData.getFacing().toString());
|
||||
}
|
||||
// Apply replacements and color and then set it on the sign
|
||||
for(int i = 0; i < signLines.length; i++) {
|
||||
if(signLines[i] == null) {
|
||||
signState.setLine(i, "");
|
||||
continue;
|
||||
}
|
||||
signLines[i] = region.applyAllReplacements(signLines[i]);
|
||||
signLines[i] = Utils.applyColors(signLines[i]);
|
||||
signState.setLine(i, signLines[i]);
|
||||
}
|
||||
signState.update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the sign needs to update periodically
|
||||
* @return true if it needs periodic updates, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
// Get the prefix
|
||||
String prefix = "signProfiles."+getProfile()+"."+region.getState().getValue().toLowerCase()+".line";
|
||||
String line;
|
||||
// Get the lines
|
||||
for(int i = 1; i < 5; i++) {
|
||||
line = plugin.getConfig().getString(prefix+i);
|
||||
if(line != null && line.length() != 0 && line.contains(AreaShop.tagTimeLeft)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run commands when a player clicks a sign
|
||||
* @param clicker The player that clicked the sign
|
||||
* @param clickType The type of clicking
|
||||
* @return true if the commands ran successfully, false if any of them failed
|
||||
*/
|
||||
public boolean runSignCommands(Player clicker, GeneralRegion.ClickType clickType) {
|
||||
// Get the profile set in the config
|
||||
String profile = region.getConfig().getString("general.signs."+key+".profile");
|
||||
if(profile == null || profile.length() == 0) {
|
||||
profile = region.getStringSetting("general.signProfile");
|
||||
}
|
||||
|
||||
// Get paths (state may change after running them)
|
||||
String playerPath = "signProfiles."+profile+"."+region.getState().getValue().toLowerCase()+"."+clickType.getValue()+"Player";
|
||||
String consolePath = "signProfiles."+profile+"."+region.getState().getValue().toLowerCase()+"."+clickType.getValue()+"Console";
|
||||
|
||||
// Run player commands if specified
|
||||
List<String> playerCommands = new ArrayList<>();
|
||||
for(String command : plugin.getConfig().getStringList(playerPath)) {
|
||||
playerCommands.add(command.replace(AreaShop.tagClicker, clicker.getName()));
|
||||
}
|
||||
region.runCommands(clicker, playerCommands);
|
||||
|
||||
// Run console commands if specified
|
||||
List<String> consoleCommands = new ArrayList<>();
|
||||
for(String command : plugin.getConfig().getStringList(consolePath)) {
|
||||
consoleCommands.add(command.replace(AreaShop.tagClicker, clicker.getName()));
|
||||
}
|
||||
region.runCommands(Bukkit.getConsoleSender(), consoleCommands);
|
||||
|
||||
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,602 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.handlers.worldguard.v7.WorldGuardHandler;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.areashop.tools.Value;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class TeleportFeature extends RegionFeature {
|
||||
|
||||
public TeleportFeature() {
|
||||
}
|
||||
|
||||
public TeleportFeature(GeneralRegion region) {
|
||||
setRegion(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a certain location is safe to teleport to.
|
||||
*
|
||||
* @param location The location to check
|
||||
* @return true if it is safe, otherwise false
|
||||
*/
|
||||
private static boolean isSafe(Location location) {
|
||||
Block feet = location.getBlock();
|
||||
Block head = feet.getRelative(BlockFace.UP);
|
||||
Block below = feet.getRelative(BlockFace.DOWN);
|
||||
Block above = head.getRelative(BlockFace.UP);
|
||||
|
||||
// Check the block at the feet and head of the player
|
||||
if ((feet.getType().isSolid() && !canSpawnIn(feet.getType())) || feet.isLiquid()) {
|
||||
return false;
|
||||
} else if ((head.getType().isSolid() && !canSpawnIn(head.getType())) || head.isLiquid()) {
|
||||
return false;
|
||||
} else if (!below.getType().isSolid() || cannotSpawnOn(below.getType()) || below.isLiquid()) {
|
||||
return false;
|
||||
} else if (above.isLiquid() || cannotSpawnBeside(above.getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all blocks around the player (below foot level, foot level, head level and above head level)
|
||||
Set<Material> around = new HashSet<>();
|
||||
for (int y = 0; y <= 3; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
// Skip blocks in the column of the player
|
||||
if (x == 0 && z == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
around.add(below.getRelative(x, y, z).getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the blocks around the player
|
||||
for (Material material : around) {
|
||||
if (cannotSpawnBeside(material)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn in here.
|
||||
*
|
||||
* @param material Material to check (assumed that this is at the feet or head level)
|
||||
* @return true when it is safe to spawn inside, otherwise false
|
||||
*/
|
||||
private static boolean canSpawnIn(Material material) {
|
||||
String name = material.name();
|
||||
return name.contains("DOOR")
|
||||
|| name.contains("SIGN")
|
||||
|| name.contains("PLATE") // Redstone plates
|
||||
|| name.equals("DRAGON_EGG");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn on here.
|
||||
*
|
||||
* @param material Material to check (assumed that this is below the feet)
|
||||
* @return true when it is safe to spawn on top of, otherwise false
|
||||
*/
|
||||
private static boolean cannotSpawnOn(Material material) {
|
||||
String name = material.name();
|
||||
return name.equals("CACTUS")
|
||||
|| name.contains("PISTON")
|
||||
|| name.contains("SIGN")
|
||||
|| name.contains("DOOR")
|
||||
|| name.contains("PLATE")
|
||||
|| name.contains("REDSTONE_LAMP")
|
||||
|| name.contains("FENCE")
|
||||
|| name.contains("GLASS_PANE") || name.contains("THIN_GLASS")
|
||||
|| name.equals("DRAGON_EGG")
|
||||
|| name.contains("MAGMA");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn next to it.
|
||||
*
|
||||
* @param material Material to check (assumed that this is somewhere around the player)
|
||||
* @return true when it is safe to spawn next to, otherwise false
|
||||
*/
|
||||
private static boolean cannotSpawnBeside(Material material) {
|
||||
String name = material.name();
|
||||
return name.contains("LAVA")
|
||||
|| name.contains("CACTUS")
|
||||
|| name.equals("FIRE")
|
||||
|| name.contains("MAGMA");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the teleportlocation set for this region.
|
||||
*
|
||||
* @return The teleport location, or null if not set
|
||||
*/
|
||||
public Location getTeleportLocation() {
|
||||
return Utils.configToLocation(getRegion().getConfigurationSectionSetting("general.teleportLocation"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region has a teleportLocation specified.
|
||||
*
|
||||
* @return true if the region has a teleportlocation, false otherwise
|
||||
*/
|
||||
public boolean hasTeleportLocation() {
|
||||
return getRegion().getConfigurationSectionSetting("general.teleportLocation") != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the teleport location of this region.
|
||||
*
|
||||
* @param location The location to set as teleport location
|
||||
*/
|
||||
public void setTeleport(Location location) {
|
||||
if (location == null) {
|
||||
getRegion().setSetting("general.teleportLocation", null);
|
||||
} else {
|
||||
getRegion().setSetting("general.teleportLocation", Utils.locationToConfig(location, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region or sign.
|
||||
*
|
||||
* @param player Player that should be teleported
|
||||
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
|
||||
* @param checkRestrictions Set to true if teleport permissions should be checked, false otherwise, also toggles cross-world check
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public CompletableFuture<Boolean> teleportPlayer(Player player, boolean toSign, boolean checkRestrictions) {
|
||||
|
||||
// Check basics
|
||||
if (getRegion().getWorld() == null) {
|
||||
getRegion().message(player, "general-noWorld");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
if (getRegion().getRegion() == null) {
|
||||
getRegion().message(player, "general-noRegion");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
if (checkRestrictions) {
|
||||
// Check correct world
|
||||
if (!getRegion().getBooleanSetting("general.teleportCrossWorld") && !player.getWorld().equals(getRegion().getWorld())) {
|
||||
getRegion().message(player, "teleport-wrongWorld", player.getWorld().getName());
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
boolean owner = player.getUniqueId().equals(getRegion().getOwner());
|
||||
boolean friend = getRegion().getFriendsFeature().getFriends().contains(player.getUniqueId());
|
||||
boolean available = getRegion().isAvailable();
|
||||
// Teleport to sign instead if they dont have permission for teleporting to region
|
||||
if ((!toSign && owner && !player.hasPermission("areashop.teleport") && player.hasPermission("areashop.teleportsign")
|
||||
|| !toSign && !owner && !friend && !player.hasPermission("areashop.teleportall") && player.hasPermission("areashop.teleportsignall")
|
||||
|| !toSign && !owner && friend && !player.hasPermission("areashop.teleportfriend") && player.hasPermission("areashop.teleportfriendsign")
|
||||
|| !toSign && !owner && !friend && available && !player.hasPermission("areashop.teleportavailable") && player.hasPermission("areashop.teleportavailablesign"))) {
|
||||
getRegion().message(player, "teleport-changedToSign");
|
||||
toSign = true;
|
||||
}
|
||||
// Check permissions
|
||||
if (owner && !available && !player.hasPermission("areashop.teleport") && !toSign) {
|
||||
getRegion().message(player, "teleport-noPermission");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (!owner && !available && !player.hasPermission("areashop.teleportall") && !toSign && !friend) {
|
||||
getRegion().message(player, "teleport-noPermissionOther");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (!owner && !available && !player.hasPermission("areashop.teleportfriend") && !toSign && friend) {
|
||||
getRegion().message(player, "teleport-noPermissionFriend");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (available && !player.hasPermission("areashop.teleportavailable") && !toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionAvailable");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (owner && !available && !player.hasPermission("areashop.teleportsign") && toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionSign");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (!owner && !available && !player.hasPermission("areashop.teleportsignall") && toSign && !friend) {
|
||||
getRegion().message(player, "teleport-noPermissionOtherSign");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (!owner && !available && !player.hasPermission("areashop.teleportfriendsign") && toSign && friend) {
|
||||
getRegion().message(player, "teleport-noPermissionFriendSign");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else if (available && !player.hasPermission("areashop.teleportavailablesign") && toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionAvailableSign");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the starting location
|
||||
Value<Boolean> toSignRef = new Value<>(toSign);
|
||||
Location startLocation = getStartLocation(player, toSignRef);
|
||||
toSign = toSignRef.get();
|
||||
|
||||
boolean insideRegion;
|
||||
if (toSign) {
|
||||
insideRegion = getRegion().getBooleanSetting("general.teleportToSignIntoRegion");
|
||||
} else {
|
||||
insideRegion = getRegion().getBooleanSetting("general.teleportIntoRegion");
|
||||
}
|
||||
|
||||
// Check locations starting from startLocation and then a cube that increases
|
||||
// radius around that (until no block in the region is found at all cube sides)
|
||||
ProtectedRegion worldguardRegion = getRegion().getRegion();
|
||||
boolean blocksInRegion = worldguardRegion.contains(startLocation.getBlockX(), startLocation.getBlockY(), startLocation.getBlockZ());
|
||||
if (!blocksInRegion && insideRegion) {
|
||||
getRegion().message(player, "teleport-blocked");
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
// Tracking of which sides to continue the search
|
||||
final World world = getRegion().getWorld();
|
||||
BlockVector3 min = worldguardRegion.getMinimumPoint();
|
||||
BlockVector3 max = worldguardRegion.getMaximumPoint();
|
||||
|
||||
for (int x = min.getX(); x < max.getX(); x += 16) {
|
||||
for (int z = min.getZ(); z < max.getZ(); z += 16) {
|
||||
PaperLib.getChunkAtAsync(world, x >> 4, z >> 4);
|
||||
}
|
||||
}
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
final boolean finalToSign = toSign;
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
boolean blocksInRegionCopy = blocksInRegion;
|
||||
Location safeLocation = startLocation;
|
||||
// Tries limit tracking
|
||||
int radius = 1;
|
||||
int checked = 1;
|
||||
int maxTries = plugin.getConfig().getInt("maximumTries");
|
||||
|
||||
// Tracking of which sides to continue the search
|
||||
boolean done = isSafe(safeLocation);
|
||||
boolean northDone = false, eastDone = false, southDone = false, westDone = false, topDone = false, bottomDone = false;
|
||||
boolean continueThisDirection;
|
||||
|
||||
while ((blocksInRegionCopy || !insideRegion) && !done) {
|
||||
blocksInRegionCopy = false;
|
||||
|
||||
// North side
|
||||
continueThisDirection = false;
|
||||
for (int x = -radius + 1; x <= radius && !done && !northDone; x++) {
|
||||
for (int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(x, y, -radius);
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
northDone = northDone || !continueThisDirection;
|
||||
|
||||
// East side
|
||||
continueThisDirection = false;
|
||||
for (int z = -radius + 1; z <= radius && !done && !eastDone; z++) {
|
||||
for (int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(radius, y, z);
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
eastDone = eastDone || !continueThisDirection;
|
||||
|
||||
// South side
|
||||
continueThisDirection = false;
|
||||
for (int x = radius - 1; x >= -radius && !done && !southDone; x--) {
|
||||
for (int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(x, y, radius);
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
southDone = southDone || !continueThisDirection;
|
||||
|
||||
// West side
|
||||
continueThisDirection = false;
|
||||
for (int z = radius - 1; z >= -radius && !done && !westDone; z--) {
|
||||
for (int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(-radius, y, z);
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
westDone = westDone || !continueThisDirection;
|
||||
|
||||
// Top side
|
||||
continueThisDirection = false;
|
||||
// Middle block of the top
|
||||
if ((startLocation.getBlockY() + radius) > 256) {
|
||||
topDone = true;
|
||||
}
|
||||
if (!done && !topDone) {
|
||||
safeLocation = startLocation.clone().add(0, radius, 0);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
for (int r = 1; r <= radius && !done && !topDone; r++) {
|
||||
// North
|
||||
for (int x = -r + 1; x <= r && !done; x++) {
|
||||
safeLocation = startLocation.clone().add(x, radius, -r);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// East
|
||||
for (int z = -r + 1; z <= r && !done; z++) {
|
||||
safeLocation = startLocation.clone().add(r, radius, z);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// South side
|
||||
for (int x = r - 1; x >= -r && !done; x--) {
|
||||
safeLocation = startLocation.clone().add(x, radius, r);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// West side
|
||||
for (int z = r - 1; z >= -r && !done; z--) {
|
||||
safeLocation = startLocation.clone().add(-r, radius, z);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
topDone = topDone || !continueThisDirection;
|
||||
|
||||
// Bottom side
|
||||
continueThisDirection = false;
|
||||
// Middle block of the bottom
|
||||
if (startLocation.getBlockY() - radius < 0) {
|
||||
bottomDone = true;
|
||||
}
|
||||
if (!done && !bottomDone) {
|
||||
safeLocation = startLocation.clone().add(0, -radius, 0);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
for (int r = 1; r <= radius && !done && !bottomDone; r++) {
|
||||
// North
|
||||
for (int x = -r + 1; x <= r && !done; x++) {
|
||||
safeLocation = startLocation.clone().add(x, -radius, -r);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// East
|
||||
for (int z = -r + 1; z <= r && !done; z++) {
|
||||
safeLocation = startLocation.clone().add(r, -radius, z);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// South side
|
||||
for (int x = r - 1; x >= -r && !done; x--) {
|
||||
safeLocation = startLocation.clone().add(x, -radius, r);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// West side
|
||||
for (int z = r - 1; z >= -r && !done; z--) {
|
||||
safeLocation = startLocation.clone().add(-r, -radius, z);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bottomDone = bottomDone || !continueThisDirection;
|
||||
|
||||
// Increase cube radius
|
||||
radius++;
|
||||
}
|
||||
|
||||
if (done && isSafe(safeLocation)) {
|
||||
final SignsFeature feature = getRegion().getSignsFeature();
|
||||
Collection<RegionSign> signs = feature.getSigns();
|
||||
if (finalToSign) {
|
||||
getRegion().message(player, "teleport-successSign");
|
||||
|
||||
// Let the player look at the sign
|
||||
Vector playerVector = safeLocation.toVector();
|
||||
playerVector.setY(playerVector.getY() + player.getEyeHeight(true));
|
||||
final RegionSign first = signs.iterator().next();
|
||||
Vector signVector = first.getLocation().add(0.5, 0.5, 0.5).toVector();
|
||||
Vector direction = playerVector.clone().subtract(signVector).normalize();
|
||||
safeLocation.setYaw(180 - (float) Math.toDegrees(Math.atan2(direction.getX(), direction.getZ())));
|
||||
safeLocation.setPitch(90 - (float) Math.toDegrees(Math.acos(direction.getY())));
|
||||
} else {
|
||||
getRegion().message(player, "teleport-success");
|
||||
}
|
||||
|
||||
AreaShop.debug("Found location: " + safeLocation.toString() + " Tries: " + checked);
|
||||
PaperLib.teleportAsync(player, safeLocation).thenAccept(future::complete);
|
||||
} else {
|
||||
getRegion().message(player, "teleport-noSafe", checked, maxTries);
|
||||
AreaShop.debug("No location found, checked " + checked + " spots of max " + maxTries);
|
||||
future.complete(false);
|
||||
}
|
||||
}, 1);
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region or sign when he has permissions for it.
|
||||
*
|
||||
* @param player Player that should be teleported
|
||||
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public CompletableFuture<Boolean> teleportPlayer(Player player, boolean toSign) {
|
||||
return teleportPlayer(player, toSign, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region when he has permissions for it.
|
||||
*
|
||||
* @param player Player that should be teleported
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public CompletableFuture<Boolean> teleportPlayer(Player player) {
|
||||
return teleportPlayer(player, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start location of a safe teleport search.
|
||||
*
|
||||
* @param player The player to get it for
|
||||
* @param toSign true to try teleporting to the first sign, false for teleporting to the region
|
||||
* @return The start location
|
||||
*/
|
||||
private Location getStartLocation(Player player, Value<Boolean> toSign) {
|
||||
Location startLocation = null;
|
||||
ProtectedRegion worldguardRegion = getRegion().getRegion();
|
||||
|
||||
// Try to get sign location
|
||||
Collection<RegionSign> signs = getRegion().getSignsFeature().getSigns();
|
||||
boolean signAvailable = !signs.isEmpty();
|
||||
if (toSign.get()) {
|
||||
RegionSign sign = signs.iterator().next();
|
||||
if (signAvailable) {
|
||||
// Use the location 1 below the sign to prevent weird spawing above the sign
|
||||
startLocation = sign.getLocation(); //.subtract(0.0, 1.0, 0.0);
|
||||
startLocation.setPitch(player.getLocation().getPitch());
|
||||
startLocation.setYaw(player.getLocation().getYaw());
|
||||
|
||||
// Move player x blocks away from the sign
|
||||
double distance = getRegion().getDoubleSetting("general.teleportSignDistance");
|
||||
if (distance > 0) {
|
||||
BlockFace facing = sign.getFacing();
|
||||
Vector facingVector = new Vector(facing.getModX(), facing.getModY(), facing.getModZ())
|
||||
.normalize()
|
||||
.multiply(distance);
|
||||
startLocation.setX(startLocation.getBlockX() + 0.5);
|
||||
startLocation.setZ(startLocation.getBlockZ() + 0.5);
|
||||
startLocation.add(facingVector);
|
||||
}
|
||||
} else {
|
||||
// No sign available
|
||||
getRegion().message(player, "teleport-changedToNoSign");
|
||||
toSign.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Use teleportation location that is set for the region
|
||||
if (startLocation == null && hasTeleportLocation()) {
|
||||
startLocation = getTeleportLocation();
|
||||
}
|
||||
|
||||
// Calculate a default location
|
||||
if (startLocation == null) {
|
||||
final WorldGuardInterface handler = AreaShop.getInstance().getWorldGuardHandler();
|
||||
// Set to block in the middle, y configured in the config
|
||||
Vector regionMin = handler.getMinimumPoint(worldguardRegion);
|
||||
Vector regionMax = handler.getMaximumPoint(worldguardRegion);
|
||||
Vector middle = regionMin.clone().midpoint(regionMax);
|
||||
String configSetting = getRegion().getStringSetting("general.teleportLocationY");
|
||||
if ("bottom".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(regionMin.getBlockY());
|
||||
} else if ("top".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(regionMax.getBlockY());
|
||||
} else if ("middle".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(middle.getBlockY());
|
||||
} else {
|
||||
try {
|
||||
int vertical = Integer.parseInt(configSetting);
|
||||
middle = middle.setY(vertical);
|
||||
} catch (NumberFormatException e) {
|
||||
AreaShop.warn("Could not parse general.teleportLocationY: '" + configSetting + "'");
|
||||
}
|
||||
}
|
||||
final Location location = player.getLocation();
|
||||
startLocation = new Location(getRegion().getWorld(), middle.getX(), middle.getY(), middle.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
// Set location in the center of the block
|
||||
startLocation.setX(startLocation.getBlockX() + 0.5);
|
||||
startLocation.setZ(startLocation.getBlockZ() + 0.5);
|
||||
|
||||
return startLocation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+112
-53
@@ -6,61 +6,74 @@ import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.notify.RegionUpdateEvent;
|
||||
import me.wiefferink.areashop.messages.Message;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.RegionAccessSet;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
public class WorldGuardRegionFlagsFeature extends RegionFeature {
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(RegionUpdateEvent event) {
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
updateRegionFlags(event.getRegion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region flags/options to the values of a ConfigurationSection
|
||||
* Set the region flags/options to the values of a ConfigurationSection.
|
||||
* @param region The region to update the flags for
|
||||
* @return true if the flags have been set correctly, otherwise false
|
||||
*/
|
||||
protected boolean updateRegionFlags(GeneralRegion region) {
|
||||
private boolean updateRegionFlags(GeneralRegion region) {
|
||||
boolean result = true;
|
||||
|
||||
// General region flags
|
||||
String allPath = "flagProfiles."+region.getStringSetting("general.flagProfile")+".ALL";
|
||||
ConfigurationSection generalFlags = plugin.getConfig().getConfigurationSection(allPath);
|
||||
if(plugin.getConfig().isSet(allPath) && generalFlags != null) { // Explicitely check if it is set, so don't apply if only in the default config
|
||||
result = updateRegionFlags(region, generalFlags);
|
||||
// Get section defining the region flag profile
|
||||
ConfigurationSection flagProfileSection = region.getConfigurationSectionSetting("general.flagProfile", "flagProfiles");
|
||||
if(flagProfileSection == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Specific region flags
|
||||
String specificPath = "flagProfiles."+region.getStringSetting("general.flagProfile")+"."+region.getState().getValue();
|
||||
if(plugin.getConfig().isSet(specificPath)) { // Do no apply default flags if they are removed from the active config
|
||||
ConfigurationSection specificFlags = plugin.getConfig().getConfigurationSection(specificPath);
|
||||
result = result && specificFlags != null && updateRegionFlags(region, specificFlags);
|
||||
// Region flags for all states
|
||||
ConfigurationSection allFlags = flagProfileSection.getConfigurationSection("ALL");
|
||||
if(allFlags != null) {
|
||||
result = updateRegionFlags(region, allFlags);
|
||||
}
|
||||
|
||||
// Region flags for the current state
|
||||
ConfigurationSection stateFlags = flagProfileSection.getConfigurationSection(region.getState().getValue());
|
||||
|
||||
// If in reselling mode, fallback to 'resale' section if 'resell' is not found (legacy configuration problem: https://github.com/NLthijs48/AreaShop/issues/303)
|
||||
if(stateFlags == null && region.getState() == GeneralRegion.RegionState.RESELL) {
|
||||
stateFlags = flagProfileSection.getConfigurationSection("resale");
|
||||
}
|
||||
if(stateFlags != null) {
|
||||
result &= updateRegionFlags(region, stateFlags);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region flags/options to the values of a ConfigurationSection
|
||||
* Set the region flags/options to the values of a ConfigurationSection.
|
||||
* @param region The region to update the flags for
|
||||
* @param flags The flags to apply
|
||||
* @param flags The flags to apply
|
||||
* @return true if the flags have been set correctly, otherwise false
|
||||
*/
|
||||
protected boolean updateRegionFlags(GeneralRegion region, ConfigurationSection flags) {
|
||||
private boolean updateRegionFlags(GeneralRegion region, ConfigurationSection flags) {
|
||||
boolean result = true;
|
||||
|
||||
Set<String> flagNames = flags.getKeys(false);
|
||||
WorldGuardPlugin worldGuard = plugin.getWorldGuard();
|
||||
|
||||
// Get the region
|
||||
ProtectedRegion wRegion = region.getRegion();
|
||||
if(wRegion == null) {
|
||||
ProtectedRegion worldguardRegion = region.getRegion();
|
||||
if(worldguardRegion == null) {
|
||||
AreaShop.debug("Region '" + region.getName() + "' does not exist, setting flags failed");
|
||||
return false;
|
||||
}
|
||||
@@ -72,31 +85,35 @@ public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
value = translateBukkitToWorldGuardColors(value);
|
||||
}
|
||||
if(flagName.equalsIgnoreCase("members")) {
|
||||
plugin.getWorldGuardHandler().setMembers(wRegion, value);
|
||||
plugin.getWorldGuardHandler().setMembers(worldguardRegion, parseAccessSet(value));
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + members.toUserFriendlyString());
|
||||
} else if(flagName.equalsIgnoreCase("owners")) {
|
||||
plugin.getWorldGuardHandler().setOwners(wRegion, value);
|
||||
plugin.getWorldGuardHandler().setOwners(worldguardRegion, parseAccessSet(value));
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + owners.toUserFriendlyString());
|
||||
} else if(flagName.equalsIgnoreCase("priority")) {
|
||||
try {
|
||||
int priority = Integer.parseInt(value);
|
||||
wRegion.setPriority(priority);
|
||||
if(worldguardRegion.getPriority() != priority) {
|
||||
worldguardRegion.setPriority(priority);
|
||||
}
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + value);
|
||||
} catch(NumberFormatException e) {
|
||||
AreaShop.warn("The value of flag "+flagName+" is not a number");
|
||||
AreaShop.warn("The value of flag " + flagName + " is not a number");
|
||||
result = false;
|
||||
}
|
||||
} else if(flagName.equalsIgnoreCase("parent")) {
|
||||
if(region.getWorld() == null || worldGuard.getRegionManager(region.getWorld()) == null) {
|
||||
if(region.getWorld() == null || plugin.getRegionManager(region.getWorld()) == null) {
|
||||
continue;
|
||||
}
|
||||
ProtectedRegion parentRegion = worldGuard.getRegionManager(region.getWorld()).getRegion(value);
|
||||
ProtectedRegion parentRegion = plugin.getRegionManager(region.getWorld()).getRegion(value);
|
||||
if(parentRegion != null) {
|
||||
try {
|
||||
wRegion.setParent(parentRegion);
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + value);
|
||||
} catch(ProtectedRegion.CircularInheritanceException e) {
|
||||
AreaShop.warn("The parent set in the config is not correct (circular inheritance)");
|
||||
if(!parentRegion.equals(worldguardRegion.getParent())) {
|
||||
try {
|
||||
worldguardRegion.setParent(parentRegion);
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + value);
|
||||
} catch(ProtectedRegion.CircularInheritanceException e) {
|
||||
AreaShop.warn("The parent set in the config is not correct (circular inheritance)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AreaShop.warn("The parent set in the config is not correct (region does not exist)");
|
||||
@@ -108,14 +125,16 @@ public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
|
||||
Flag<?> foundFlag = plugin.getWorldGuardHandler().fuzzyMatchFlag(flagName);
|
||||
if(foundFlag == null) {
|
||||
AreaShop.warn("Found wrong flag in flagProfiles section: "+flagName+", check if that is the correct WorldGuard flag");
|
||||
AreaShop.warn("Found wrong flag in flagProfiles section: " + flagName + ", check if that is the correct WorldGuard flag");
|
||||
continue;
|
||||
}
|
||||
RegionGroupFlag groupFlag = foundFlag.getRegionGroupFlag();
|
||||
if(value == null || value.isEmpty()) {
|
||||
wRegion.setFlag(foundFlag, null);
|
||||
if(groupFlag != null) {
|
||||
wRegion.setFlag(groupFlag, null);
|
||||
if(worldguardRegion.getFlag(foundFlag) != null) {
|
||||
worldguardRegion.setFlag(foundFlag, null);
|
||||
}
|
||||
if(groupFlag != null && worldguardRegion.getFlag(groupFlag) != null) {
|
||||
worldguardRegion.setFlag(groupFlag, null);
|
||||
}
|
||||
//AreaShop.debug(" Flag " + flagName + " reset (+ possible group of flag)");
|
||||
} else {
|
||||
@@ -128,7 +147,7 @@ public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
try {
|
||||
groupValue = plugin.getWorldGuardHandler().parseFlagGroupInput(groupFlag, part.substring(2));
|
||||
} catch(InvalidFlagFormat e) {
|
||||
AreaShop.warn("Found wrong group value for flag "+flagName);
|
||||
AreaShop.warn("Found wrong group value for flag " + flagName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -142,18 +161,18 @@ public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
}
|
||||
if(flagSetting != null) {
|
||||
try {
|
||||
setFlag(wRegion, foundFlag, flagSetting);
|
||||
setFlag(worldguardRegion, foundFlag, flagSetting);
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + flagSetting);
|
||||
} catch(InvalidFlagFormat e) {
|
||||
AreaShop.warn("Found wrong value for flag "+flagName);
|
||||
AreaShop.warn("Found wrong value for flag " + flagName);
|
||||
}
|
||||
}
|
||||
if(groupValue != null) {
|
||||
if(groupValue == groupFlag.getDefault()) {
|
||||
wRegion.setFlag(groupFlag, null);
|
||||
worldguardRegion.setFlag(groupFlag, null);
|
||||
//AreaShop.debug(" Group of flag " + flagName + " set to default: " + groupValue);
|
||||
} else {
|
||||
wRegion.setFlag(groupFlag, groupValue);
|
||||
worldguardRegion.setFlag(groupFlag, groupValue);
|
||||
//AreaShop.debug(" Group of flag " + flagName + " set: " + groupValue);
|
||||
}
|
||||
}
|
||||
@@ -161,28 +180,68 @@ public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
|
||||
}
|
||||
}
|
||||
// Indicate that the regions needs to be saved
|
||||
plugin.getFileManager().saveIsRequiredForRegionWorld(region.getWorldName());
|
||||
if(worldGuard.getDescription().getVersion().startsWith("5.")) {
|
||||
plugin.getFileManager().saveIsRequiredForRegionWorld(region.getWorldName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a WorldGuard region flag
|
||||
* @param region The WorldGuard region to set
|
||||
* @param flag The flag to set
|
||||
* @param value The value to set the flag to
|
||||
* @param <V> They type of flag to set
|
||||
* @throws InvalidFlagFormat When the value of the flag is wrong
|
||||
* Build an RegionAccessSet from an input that specifies player names, player uuids and groups.
|
||||
* @param input Input string defining the access set
|
||||
* @return RegionAccessSet containing the entities parsed from the input
|
||||
*/
|
||||
private <V> void setFlag(ProtectedRegion region, Flag<V> flag, String value) throws InvalidFlagFormat {
|
||||
region.setFlag(flag, plugin.getWorldGuardHandler().parseFlagInput(flag, value));
|
||||
public RegionAccessSet parseAccessSet(String input) {
|
||||
RegionAccessSet result = new RegionAccessSet();
|
||||
|
||||
String[] inputParts = input.split(", ");
|
||||
for(String access : inputParts) {
|
||||
if(access != null && !access.isEmpty()) {
|
||||
// Check for groups
|
||||
if(access.startsWith("g:")) {
|
||||
if(access.length() > 2) {
|
||||
result.getGroupNames().add(access.substring(2));
|
||||
}
|
||||
} else if(access.startsWith("n:")) {
|
||||
if(access.length() > 2) {
|
||||
result.getPlayerNames().add(access.substring(2));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
result.getPlayerUniqueIds().add(UUID.fromString(access));
|
||||
} catch(IllegalArgumentException e) {
|
||||
AreaShop.warn("Tried using '" + access + "' as uuid for a region member/owner, is your flagProfiles section correct?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the color codes you put in greeting/farewell messages to the weird color codes of WorldGuard
|
||||
* Set a WorldGuard region flag.
|
||||
* @param region The WorldGuard region to set
|
||||
* @param flag The flag to set
|
||||
* @param value The value to set the flag to
|
||||
* @param <V> They type of flag to set
|
||||
* @throws InvalidFlagFormat When the value of the flag is wrong
|
||||
*/
|
||||
private <V> void setFlag(ProtectedRegion region, Flag<V> flag, String value) throws InvalidFlagFormat {
|
||||
V current = region.getFlag(flag);
|
||||
V next = plugin.getWorldGuardHandler().parseFlagInput(flag, value);
|
||||
|
||||
if(!Objects.equals(current, next)) {
|
||||
region.setFlag(flag, next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the color codes you put in greeting/farewell messages to the weird color codes of WorldGuard.
|
||||
* @param message The message where the color codes should be translated (this message has bukkit color codes)
|
||||
* @return The string with the WorldGuard color codes
|
||||
*/
|
||||
public String translateBukkitToWorldGuardColors(String message) {
|
||||
private String translateBukkitToWorldGuardColors(String message) {
|
||||
String result = message;
|
||||
result = result.replace("&c", "&r");
|
||||
result = result.replace("&4", "&R");
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sign that is connected to a region to display information and interact with the region.
|
||||
*/
|
||||
public class RegionSign {
|
||||
|
||||
private final SignsFeature signsFeature;
|
||||
private final String key;
|
||||
|
||||
public RegionSign(SignsFeature signsFeature, String key) {
|
||||
this.signsFeature = signsFeature;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of this sign.
|
||||
*
|
||||
* @return The location of this sign
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return Utils.configToLocation(getRegion().getConfig().getConfigurationSection("general.signs." + key + ".location"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Location string to be used as key in maps.
|
||||
*
|
||||
* @return Location string
|
||||
*/
|
||||
public String getStringLocation() {
|
||||
return SignsFeature.locationToString(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk string to be used as key in maps.
|
||||
*
|
||||
* @return Chunk string
|
||||
*/
|
||||
public String getStringChunk() {
|
||||
return SignsFeature.chunkToString(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region this sign is linked to.
|
||||
*
|
||||
* @return The region this sign is linked to
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return signsFeature.getRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this sign from the region.
|
||||
*/
|
||||
public void remove() {
|
||||
getLocation().getBlock().setType(Material.AIR);
|
||||
signsFeature.getSignsRef().remove(getStringLocation());
|
||||
SignsFeature.getAllSigns().remove(getStringLocation());
|
||||
SignsFeature.getSignsByChunk().get(getStringChunk()).remove(this);
|
||||
getRegion().setSetting("general.signs." + key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ConfigurationSection defining the sign layout.
|
||||
*
|
||||
* @return The sign layout config
|
||||
*/
|
||||
public ConfigurationSection getProfile() {
|
||||
return getRegion().getConfigurationSectionSetting("general.signProfile", "signProfiles", getRegion().getConfig().get("general.signs." + key + ".profile"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the facing of the sign as saved in the config.
|
||||
*
|
||||
* @return BlockFace the sign faces, or null if unknown
|
||||
*/
|
||||
public BlockFace getFacing() {
|
||||
try {
|
||||
return BlockFace.valueOf(getRegion().getConfig().getString("general.signs." + key + ".facing"));
|
||||
} catch (NullPointerException | IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material of the sign as saved in the config.
|
||||
*
|
||||
* @return Material of the sign, usually {@link Material#WALL_SIGN}, {@link Material#SIGN}, or one of the other wood types (different result for 1.13-), Material.AIR if none.
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
String name = getRegion().getConfig().getString("general.signs." + key + ".signType");
|
||||
Material result = Materials.signNameToMaterial(name);
|
||||
return result == null ? Material.AIR : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this sign.
|
||||
*
|
||||
* @return true if the update was successful, otherwise false
|
||||
*/
|
||||
public boolean update() {
|
||||
// Ignore updates of signs in chunks that are not loaded
|
||||
Location signLocation = getLocation();
|
||||
if (signLocation == null
|
||||
|| signLocation.getWorld() == null
|
||||
|| !signLocation.getWorld().isChunkLoaded(signLocation.getBlockX() >> 4, signLocation.getBlockZ() >> 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getRegion().isDeleted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YamlConfiguration regionConfig = getRegion().getConfig();
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
Block block = signLocation.getBlock();
|
||||
if (signConfig == null || !signConfig.isSet(getRegion().getState().getValue())) {
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue());
|
||||
|
||||
// Get the lines
|
||||
String[] signLines = new String[4];
|
||||
boolean signEmpty = true;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
signLines[i] = stateConfig.getString("line" + (i + 1));
|
||||
signEmpty &= (signLines[i] == null || signLines[i].isEmpty());
|
||||
}
|
||||
if (signEmpty) {
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed
|
||||
if (!Materials.isSign(block.getType())) {
|
||||
Material signType = getMaterial();
|
||||
if (signType.name().contains("SIGN")) {
|
||||
// Don't do physics here, we first need to update the direction
|
||||
block.setType(signType, false);
|
||||
BlockData data = block.getBlockData();
|
||||
if (data instanceof WallSign) {
|
||||
((WallSign) data).setFacing(getFacing());
|
||||
} else if (data instanceof Sign) {
|
||||
((org.bukkit.block.data.type.Sign) data).setRotation(getFacing());
|
||||
}
|
||||
block.setBlockData(data, true);
|
||||
|
||||
// Check if the sign has popped
|
||||
if (!Materials.isSign(block.getType())) {
|
||||
AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, could not set sign block back");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, RegionSign material was: " + signType.name());
|
||||
}
|
||||
}
|
||||
|
||||
// Save current rotation and type
|
||||
if (!regionConfig.isString("general.signs." + key + ".signType")) {
|
||||
getRegion().setSetting("general.signs." + key + ".signType", block.getType().name());
|
||||
}
|
||||
if (!regionConfig.isString("general.signs." + key + ".facing")) {
|
||||
final BlockFace rotation;
|
||||
if (Materials.isSign(block.getType())) {
|
||||
BlockData data = block.getBlockData();
|
||||
if (data instanceof org.bukkit.block.data.type.Sign) {
|
||||
rotation = ((org.bukkit.block.data.type.Sign) block.getBlockData()).getRotation();
|
||||
} else if (data instanceof WallSign) {
|
||||
rotation = ((WallSign) data).getFacing();
|
||||
} else {
|
||||
rotation = null;
|
||||
}
|
||||
} else {
|
||||
rotation = null;
|
||||
}
|
||||
getRegion().setSetting("general.signs." + key + ".facing", rotation == null ? null : rotation.toString());
|
||||
}
|
||||
|
||||
// Apply replacements and color and then set it on the sign
|
||||
Sign signState = (Sign) block.getState();
|
||||
for (int i = 0; i < signLines.length; i++) {
|
||||
if (signLines[i] == null) {
|
||||
signState.setLine(i, "");
|
||||
continue;
|
||||
}
|
||||
signLines[i] = Message.fromString(signLines[i]).replacements(getRegion()).getSingle();
|
||||
signLines[i] = Utils.applyColors(signLines[i]);
|
||||
signState.setLine(i, signLines[i]);
|
||||
}
|
||||
signState.update();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the sign needs to update periodically.
|
||||
*
|
||||
* @return true if it needs periodic updates, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
if (signConfig == null || !signConfig.isSet(getRegion().getState().getValue().toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
|
||||
if (stateConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the lines for the timeleft tag
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
String line = stateConfig.getString("line" + i);
|
||||
if (line != null && !line.isEmpty() && line.contains(Message.VARIABLE_START + AreaShop.tagTimeLeft + Message.VARIABLE_END)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run commands when a player clicks a sign.
|
||||
*
|
||||
* @param clicker The player that clicked the sign
|
||||
* @param clickType The type of clicking
|
||||
* @return true if the commands ran successfully, false if any of them failed
|
||||
*/
|
||||
public boolean runSignCommands(Player clicker, GeneralRegion.ClickType clickType) {
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
if (signConfig == null) {
|
||||
return false;
|
||||
}
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
|
||||
|
||||
// Run player commands if specified
|
||||
List<String> playerCommands = new ArrayList<>();
|
||||
for (String command : stateConfig.getStringList(clickType.getValue() + "Player")) {
|
||||
// TODO move variable checking code to InteractiveMessenger?
|
||||
playerCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
|
||||
}
|
||||
getRegion().runCommands(clicker, playerCommands);
|
||||
|
||||
// Run console commands if specified
|
||||
List<String> consoleCommands = new ArrayList<>();
|
||||
for (String command : stateConfig.getStringList(clickType.getValue() + "Console")) {
|
||||
consoleCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
|
||||
}
|
||||
getRegion().runCommands(Bukkit.getConsoleSender(), consoleCommands);
|
||||
|
||||
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof RegionSign && ((RegionSign) object).getRegion().equals(this.getRegion()) && ((RegionSign) object).key.equals(this.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key, getRegion().getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,636 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.features.RegionFeature;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Sign;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SignsFeature extends RegionFeature {
|
||||
|
||||
private static final Map<String, RegionSign> allSigns = new ConcurrentHashMap<>();
|
||||
private static final Map<String, List<RegionSign>> signsByChunk = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, RegionSign> signs;
|
||||
|
||||
public SignsFeature() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param region The region to bind to
|
||||
*/
|
||||
public SignsFeature(GeneralRegion region) {
|
||||
setRegion(region);
|
||||
signs = new HashMap<>();
|
||||
// Setup current signs
|
||||
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
|
||||
if (signSection != null) {
|
||||
for (String signKey : signSection.getKeys(false)) {
|
||||
RegionSign sign = new RegionSign(this, signKey);
|
||||
Location location = sign.getLocation();
|
||||
if (location == null) {
|
||||
AreaShop.warn("Sign with key " + signKey + " of region " + region.getName() + " does not have a proper location");
|
||||
continue;
|
||||
}
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
||||
.add(sign);
|
||||
}
|
||||
allSigns.putAll(signs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a location to a string to use as map key.
|
||||
*
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a location
|
||||
*/
|
||||
public static String locationToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + location.getBlockX() + ";" + location.getBlockY() + ";" + location.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chunk to a string to use as map key.
|
||||
*
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a chunk
|
||||
*/
|
||||
public static String chunkToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + (location.getBlockX() >> 4) + ";" + (location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chunk to a string to use as map key.
|
||||
* Use a Location argument to prevent chunk loading!
|
||||
*
|
||||
* @param chunk The location to get the key for
|
||||
* @return A string to use in a map for a chunk
|
||||
*/
|
||||
public static String chunkToString(Chunk chunk) {
|
||||
return chunk.getWorld().getName() + ";" + chunk.getX() + ";" + chunk.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sign by a location.
|
||||
*
|
||||
* @param location The location to get the sign for
|
||||
* @return The RegionSign that is at the location, or null if none
|
||||
*/
|
||||
public static RegionSign getSignByLocation(Location location) {
|
||||
return allSigns.get(locationToString(location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map with all signs.
|
||||
*
|
||||
* @return Map with all signs: locationString -> RegionSign
|
||||
*/
|
||||
public static Map<String, RegionSign> getAllSigns() {
|
||||
return allSigns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map with signs by chunk.
|
||||
*
|
||||
* @return Map with signs by chunk: chunkString -> List<RegionSign>
|
||||
*/
|
||||
public static Map<String, List<RegionSign>> getSignsByChunk() {
|
||||
return signsByChunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Deregister signs from the registry
|
||||
if (signs != null) {
|
||||
for (Map.Entry<String, RegionSign> entry : signs.entrySet()) {
|
||||
allSigns.remove(entry.getKey());
|
||||
signsByChunk.get(entry.getValue().getStringChunk()).remove(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSignBreak(BlockBreakEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getBlock();
|
||||
// Check if it is a sign
|
||||
if (Materials.isSign(block.getType())) {
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
// Remove the sign of the rental region if the player has permission
|
||||
if (event.getPlayer().hasPermission("areashop.delsign")) {
|
||||
regionSign.remove();
|
||||
plugin.message(event.getPlayer(), "delsign-success", regionSign.getRegion());
|
||||
} else { // Cancel the breaking of the sign
|
||||
event.setCancelled(true);
|
||||
plugin.message(event.getPlayer(), "delsign-noPermission", regionSign.getRegion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onIndirectSignBreak(BlockPhysicsEvent event) {
|
||||
// Check if the block is a sign
|
||||
if (!Materials.isSign(event.getBlock().getType())) {
|
||||
return;
|
||||
}
|
||||
final Block block = event.getBlock();
|
||||
final BlockData blockData = block.getBlockData();
|
||||
final Block attachedBlock;
|
||||
if (blockData instanceof WallSign) {
|
||||
attachedBlock = block.getRelative(((WallSign) blockData).getFacing().getOppositeFace());
|
||||
} else if (blockData instanceof Sign) {
|
||||
attachedBlock = block.getRelative(BlockFace.DOWN);
|
||||
} else {
|
||||
attachedBlock = null;
|
||||
}
|
||||
|
||||
// Check if still attached to a block
|
||||
// TODO: signs cannot be placed on all blocks, improve this check to isSolid()?
|
||||
if (attachedBlock == null || attachedBlock.getType() != Material.AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the sign is really the same as a saved rent
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(event.getBlock().getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the sign so that it does not fall on the floor as an item (next region update will place it back when possible)
|
||||
AreaShop.debug("onIndirectSignBreak: Removed block of sign for", regionSign.getRegion().getName(), "at", regionSign.getStringLocation());
|
||||
event.getBlock().setType(Material.AIR);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onSignClick(PlayerInteractEvent event) {
|
||||
Block block = event.getClickedBlock();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only listen to left and right clicks on blocks
|
||||
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only care about clicking blocks
|
||||
if (!Materials.isSign(block.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this sign belongs to a region
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore players that are in sign link mode (which will handle the event itself)
|
||||
Player player = event.getPlayer();
|
||||
if (plugin.getSignlinkerManager().isInSignLinkMode(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the clicktype
|
||||
GeneralRegion.ClickType clickType = null;
|
||||
if (player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.SHIFTLEFTCLICK;
|
||||
} else if (!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.LEFTCLICK;
|
||||
} else if (player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.SHIFTRIGHTCLICK;
|
||||
} else if (!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.RIGHTCLICK;
|
||||
}
|
||||
|
||||
boolean ran = regionSign.runSignCommands(player, clickType);
|
||||
|
||||
// Only cancel event if at least one command has been executed
|
||||
event.setCancelled(ran);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if (!plugin.isReady()) {
|
||||
plugin.message(player, "general-notReady");
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockFace rotation;
|
||||
final BlockData data = event.getBlock().getBlockData();
|
||||
if (data instanceof Sign) {
|
||||
rotation = ((Sign) data).getRotation();
|
||||
} else if (data instanceof WallSign) {
|
||||
rotation = ((WallSign) data).getFacing();
|
||||
} else {
|
||||
rotation = null;
|
||||
}
|
||||
|
||||
final String line0 = event.getLine(0) == null ? "" : event.getLine(0);
|
||||
|
||||
// Check if the sign is meant for this plugin
|
||||
if (line0.contains(plugin.getConfig().getString("signTags.rent"))) {
|
||||
if (!player.hasPermission("areashop.createrent") && !player.hasPermission("areashop.createrent.member") && !player.hasPermission("areashop.createrent.owner")) {
|
||||
plugin.message(player, "setup-noPermissionRent");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
String fourthLine = event.getLine(3);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if (secondLine == null || secondLine.isEmpty()) {
|
||||
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if (regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for (ProtectedRegion pr : regions) {
|
||||
if (first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if (pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if (pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else {
|
||||
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = fourthLine != null && !fourthLine.isEmpty();
|
||||
boolean durationSet = thirdLine != null && !thirdLine.isEmpty();
|
||||
// check if all the lines are correct
|
||||
if (secondLine == null || secondLine.isEmpty()) {
|
||||
plugin.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if (region == null) {
|
||||
plugin.message(player, "cmd-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
|
||||
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, regionManager.getRegion(secondLine), event.getPlayer().getWorld(), GeneralRegion.RegionType.RENT);
|
||||
|
||||
switch (addResult) {
|
||||
case BLACKLISTED:
|
||||
plugin.message(player, "setup-blacklisted", secondLine);
|
||||
break;
|
||||
case ALREADYADDED:
|
||||
plugin.message(player, "setup-alreadyRentSign");
|
||||
break;
|
||||
case ALREADYADDEDOTHERWORLD:
|
||||
plugin.message(player, "setup-alreadyOtherWorld");
|
||||
break;
|
||||
case NOPERMISSION:
|
||||
plugin.message(player, "setup-noPermission", secondLine);
|
||||
break;
|
||||
default:
|
||||
if (thirdLine != null && !thirdLine.isEmpty() && !Utils.checkTimeFormat(thirdLine)) {
|
||||
plugin.message(player, "setup-wrongDuration");
|
||||
break;
|
||||
}
|
||||
double price = 0.0;
|
||||
if (priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(fourthLine);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add rent to the FileManager
|
||||
final RentRegion rent = new RentRegion(secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = plugin.getWorldGuardHandler().containsMember(rent.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(rent.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createrent")
|
||||
&& ((player.hasPermission("areashop.createrent.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createrent.member") && isMember)));
|
||||
|
||||
if (landlord) {
|
||||
rent.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if (priceSet) {
|
||||
rent.setPrice(price);
|
||||
}
|
||||
if (durationSet) {
|
||||
rent.setDuration(thirdLine);
|
||||
}
|
||||
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), rotation, null);
|
||||
|
||||
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(rent);
|
||||
if (addingRegionEvent.isCancelled()) {
|
||||
plugin.message(player, "general-cancelled", addingRegionEvent.getReason());
|
||||
return;
|
||||
}
|
||||
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
plugin.message(player, "setup-rentSuccess", rent);
|
||||
// Update the region after the event has written its lines
|
||||
Bukkit.getScheduler().runTask(plugin, rent::update);
|
||||
|
||||
}
|
||||
} else if (line0.contains(plugin.getConfig().getString("signTags.buy"))) {
|
||||
// Check for permission
|
||||
if (!player.hasPermission("areashop.createbuy") && !player.hasPermission("areashop.createbuy.member") && !player.hasPermission("areashop.createbuy.owner")) {
|
||||
plugin.message(player, "setup-noPermissionBuy");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if (secondLine == null || secondLine.isEmpty()) {
|
||||
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if (regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for (ProtectedRegion pr : regions) {
|
||||
if (first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if (pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if (pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else {
|
||||
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = thirdLine != null && !thirdLine.isEmpty();
|
||||
// Check if all the lines are correct
|
||||
if (secondLine == null || secondLine.isEmpty()) {
|
||||
plugin.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if (region == null) {
|
||||
plugin.message(player, "cmd-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, region, event.getPlayer().getWorld(), GeneralRegion.RegionType.BUY);
|
||||
if (addResult == FileManager.AddResult.BLACKLISTED) {
|
||||
plugin.message(player, "setup-blacklisted", secondLine);
|
||||
} else if (addResult == FileManager.AddResult.ALREADYADDED) {
|
||||
plugin.message(player, "setup-alreadyRentSign");
|
||||
} else if (addResult == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
||||
plugin.message(player, "setup-alreadyOtherWorld");
|
||||
} else if (addResult == FileManager.AddResult.NOPERMISSION) {
|
||||
plugin.message(player, "setup-noPermission", secondLine);
|
||||
} else {
|
||||
double price = 0.0;
|
||||
if (priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(thirdLine);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add buy to the FileManager
|
||||
final BuyRegion buy = new BuyRegion(secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = plugin.getWorldGuardHandler().containsMember(buy.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(buy.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createbuy")
|
||||
&& ((player.hasPermission("areashop.createbuy.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createbuy.member") && isMember)));
|
||||
|
||||
if (landlord) {
|
||||
buy.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if (priceSet) {
|
||||
buy.setPrice(price);
|
||||
}
|
||||
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), rotation, null);
|
||||
|
||||
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(buy);
|
||||
if (addingRegionEvent.isCancelled()) {
|
||||
plugin.message(player, "general-cancelled", addingRegionEvent.getReason());
|
||||
return;
|
||||
}
|
||||
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
plugin.message(player, "setup-buySuccess", buy);
|
||||
// Update the region after the event has written its lines
|
||||
Bukkit.getScheduler().runTask(plugin, buy::update);
|
||||
}
|
||||
} else if (event.getLine(0).contains(plugin.getConfig().getString("signTags.add"))) {
|
||||
// Check for permission
|
||||
if (!player.hasPermission("areashop.addsign")) {
|
||||
plugin.message(player, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
GeneralRegion region;
|
||||
if (secondLine != null && !secondLine.isEmpty()) {
|
||||
// Get region by secondLine of the sign
|
||||
region = plugin.getFileManager().getRegion(secondLine);
|
||||
if (region == null) {
|
||||
plugin.message(player, "addSign-notRegistered", secondLine);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(event.getBlock().getLocation());
|
||||
if (regions.isEmpty()) {
|
||||
plugin.message(player, "addsign-noRegions");
|
||||
return;
|
||||
} else if (regions.size() > 1) {
|
||||
plugin.message(player, "addsign-couldNotDetectSign", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
String profile = thirdLine == null || thirdLine.isEmpty() ? null : thirdLine;
|
||||
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), rotation, profile);
|
||||
if (profile == null) {
|
||||
plugin.message(player, "addsign-success", region);
|
||||
} else {
|
||||
plugin.message(player, "addsign-successProfile", thirdLine, region);
|
||||
}
|
||||
|
||||
// Update the region later because this event will do it first
|
||||
Bukkit.getScheduler().runTask(plugin, region::update);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
event.getRegion().getSignsFeature().update();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
List<RegionSign> chunkSigns = signsByChunk.get(chunkToString(event.getChunk()));
|
||||
if (chunkSigns == null) {
|
||||
return;
|
||||
}
|
||||
int batchSize = Math.max(chunkSigns.size() / 10, 10);
|
||||
Utils.runAsBatches(chunkSigns, batchSize, RegionSign::update, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all signs connected to this region.
|
||||
*
|
||||
* @return true if all signs are updated correctly, false if one or more updates failed
|
||||
*/
|
||||
public boolean update() {
|
||||
boolean result = true;
|
||||
for (RegionSign sign : signs.values()) {
|
||||
result &= sign.update();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the signs need periodic updating.
|
||||
*
|
||||
* @return true if one or more of the signs need periodic updating, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
for (RegionSign sign : signs.values()) {
|
||||
if (sign.needsPeriodicUpdate()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signs of this region.
|
||||
*
|
||||
* @return List of signs
|
||||
*/
|
||||
public Collection<RegionSign> getSigns() {
|
||||
return new HashSet<>(signs.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signs of this region.
|
||||
*
|
||||
* @return Map with signs: locationString -> RegionSign
|
||||
*/
|
||||
Map<String, RegionSign> getSignsRef() {
|
||||
return signs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list with all sign locations.
|
||||
*
|
||||
* @return A List with all sign locations
|
||||
*/
|
||||
public List<Location> getSignLocations() {
|
||||
List<Location> result = new ArrayList<>();
|
||||
for (RegionSign sign : signs.values()) {
|
||||
result.add(sign.getLocation());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sign to this region.
|
||||
*
|
||||
* @param location The location of the sign
|
||||
* @param signType The type of the sign (WALL_SIGN or SIGN_POST)
|
||||
* @param facing The orientation of the sign
|
||||
* @param profile The profile to use with this sign (null for default)
|
||||
*/
|
||||
public void addSign(Location location, Material signType, BlockFace facing, String profile) {
|
||||
int i = 0;
|
||||
while (getRegion().getConfig().isSet("general.signs." + i)) {
|
||||
i++;
|
||||
}
|
||||
String signPath = "general.signs." + i + ".";
|
||||
getRegion().setSetting(signPath + "location", Utils.locationToConfig(location));
|
||||
getRegion().setSetting(signPath + "facing", facing != null ? facing.name() : null);
|
||||
getRegion().setSetting(signPath + "signType", signType != null ? signType.name() : null);
|
||||
if (profile != null && !profile.isEmpty()) {
|
||||
getRegion().setSetting(signPath + "profile", profile);
|
||||
}
|
||||
// Add to the map
|
||||
RegionSign sign = new RegionSign(this, i + "");
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
allSigns.put(sign.getStringLocation(), sign);
|
||||
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
||||
.add(sign);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,743 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 Tyler Blair. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and contributors and should not be interpreted as representing official policies,
|
||||
* either expressed or implied, of anybody else.
|
||||
*/
|
||||
package me.wiefferink.areashop.lib;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
/**
|
||||
* The current revision number
|
||||
*/
|
||||
private final static int REVISION = 7;
|
||||
|
||||
/**
|
||||
* The base url of the metrics domain
|
||||
*/
|
||||
private static final String BASE_URL = "http://report.mcstats.org";
|
||||
|
||||
/**
|
||||
* The url used to report a server's status
|
||||
*/
|
||||
private static final String REPORT_URL = "/plugin/%s";
|
||||
|
||||
/**
|
||||
* Interval of time to ping (in minutes)
|
||||
*/
|
||||
private static final int PING_INTERVAL = 15;
|
||||
|
||||
/**
|
||||
* The plugin this metrics submits for
|
||||
*/
|
||||
private final Plugin plugin;
|
||||
|
||||
/**
|
||||
* All of the custom graphs to submit to metrics
|
||||
*/
|
||||
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
|
||||
|
||||
/**
|
||||
* The plugin configuration file
|
||||
*/
|
||||
private final YamlConfiguration configuration;
|
||||
|
||||
/**
|
||||
* The plugin configuration file
|
||||
*/
|
||||
private final File configurationFile;
|
||||
|
||||
/**
|
||||
* Unique server id
|
||||
*/
|
||||
private final String guid;
|
||||
|
||||
/**
|
||||
* Debug mode
|
||||
*/
|
||||
private final boolean debug;
|
||||
|
||||
/**
|
||||
* Lock for synchronization
|
||||
*/
|
||||
private final Object optOutLock = new Object();
|
||||
|
||||
/**
|
||||
* The scheduled task
|
||||
*/
|
||||
private volatile BukkitTask task = null;
|
||||
|
||||
public Metrics(final Plugin plugin) throws IOException {
|
||||
if(plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null");
|
||||
}
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
// load the config
|
||||
configurationFile = getConfigFile();
|
||||
configuration = YamlConfiguration.loadConfiguration(configurationFile);
|
||||
|
||||
// add some defaults
|
||||
configuration.addDefault("opt-out", false);
|
||||
configuration.addDefault("guid", UUID.randomUUID().toString());
|
||||
configuration.addDefault("debug", false);
|
||||
|
||||
// Do we need to create the file?
|
||||
if(configuration.get("guid", null) == null) {
|
||||
configuration.options().header("http://mcstats.org").copyDefaults(true);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Load the guid then
|
||||
guid = configuration.getString("guid");
|
||||
debug = configuration.getBoolean("debug", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics
|
||||
* website. Plotters can be added to the graph object returned.
|
||||
* @param name The name of the graph
|
||||
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
|
||||
*/
|
||||
public Graph createGraph(final String name) {
|
||||
if(name == null) {
|
||||
throw new IllegalArgumentException("Graph name cannot be null");
|
||||
}
|
||||
|
||||
// Construct the graph object
|
||||
final Graph graph = new Graph(name);
|
||||
|
||||
// Now we can add our graph
|
||||
graphs.add(graph);
|
||||
|
||||
// and return back
|
||||
return graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
|
||||
* @param graph The name of the graph
|
||||
*/
|
||||
public void addGraph(final Graph graph) {
|
||||
if(graph == null) {
|
||||
throw new IllegalArgumentException("Graph cannot be null");
|
||||
}
|
||||
|
||||
graphs.add(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
|
||||
* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
|
||||
* ticks.
|
||||
* @return True if statistics measuring is running, otherwise false.
|
||||
*/
|
||||
public boolean start() {
|
||||
synchronized(optOutLock) {
|
||||
// Did we opt out?
|
||||
if(isOptOut()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is metrics already running?
|
||||
if(task != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
|
||||
|
||||
private boolean firstPost = true;
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
// This has to be synchronized or it can collide with the disable method.
|
||||
synchronized(optOutLock) {
|
||||
// Disable Task, if it is running and the server owner decided to opt-out
|
||||
if(isOptOut() && task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
// Tell all plotters to stop gathering information.
|
||||
for(Graph graph : graphs) {
|
||||
graph.onOptOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We use the inverse of firstPost because if it is the first time we are posting,
|
||||
// it is not a interval ping, so it evaluates to FALSE
|
||||
// Each time thereafter it will evaluate to TRUE, i.e PING!
|
||||
postPlugin(!firstPost);
|
||||
|
||||
// After the first post we set firstPost to false
|
||||
// Each post thereafter will be a ping
|
||||
firstPost = false;
|
||||
} catch(IOException e) {
|
||||
if(debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the server owner denied plugin metrics?
|
||||
* @return true if metrics should be opted out of it
|
||||
*/
|
||||
public boolean isOptOut() {
|
||||
synchronized(optOutLock) {
|
||||
try {
|
||||
// Reload the metrics file
|
||||
configuration.load(getConfigFile());
|
||||
} catch(IOException ex) {
|
||||
if(debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
} catch(InvalidConfigurationException ex) {
|
||||
if(debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return configuration.getBoolean("opt-out", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
|
||||
*/
|
||||
public void enable() throws IOException {
|
||||
// This has to be synchronized or it can collide with the check in the task.
|
||||
synchronized(optOutLock) {
|
||||
// Check if the server owner has already set opt-out, if not, set it.
|
||||
if(isOptOut()) {
|
||||
configuration.set("opt-out", false);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Enable Task, if it is not running
|
||||
if(task == null) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
|
||||
*/
|
||||
public void disable() throws IOException {
|
||||
// This has to be synchronized or it can collide with the check in the task.
|
||||
synchronized(optOutLock) {
|
||||
// Check if the server owner has already set opt-out, if not, set it.
|
||||
if(!isOptOut()) {
|
||||
configuration.set("opt-out", true);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Disable Task, if it is running
|
||||
if(task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
|
||||
* @return the File object for the config file
|
||||
*/
|
||||
public File getConfigFile() {
|
||||
// I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
|
||||
// is to abuse the plugin object we already have
|
||||
// plugin.getDataFolder() => base/plugins/PluginA/
|
||||
// pluginsFolder => base/plugins/
|
||||
// The base is not necessarily relative to the startup directory.
|
||||
File pluginsFolder = plugin.getDataFolder().getParentFile();
|
||||
|
||||
// return => base/plugins/PluginMetrics/config.yml
|
||||
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the online player (backwards compatibility)
|
||||
* @return online player amount
|
||||
*/
|
||||
private int getOnlinePlayers() {
|
||||
try {
|
||||
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
|
||||
if(onlinePlayerMethod.getReturnType().equals(Collection.class)) {
|
||||
return ((Collection<?>)onlinePlayerMethod.invoke(Bukkit.getServer())).size();
|
||||
} else {
|
||||
return ((Player[])onlinePlayerMethod.invoke(Bukkit.getServer())).length;
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
if(debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method that posts a plugin to the metrics website
|
||||
*/
|
||||
private void postPlugin(final boolean isPing) throws IOException {
|
||||
// Server software specific section
|
||||
PluginDescriptionFile description = plugin.getDescription();
|
||||
String pluginName = description.getName();
|
||||
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
|
||||
String pluginVersion = description.getVersion();
|
||||
String serverVersion = Bukkit.getVersion();
|
||||
int playersOnline = this.getOnlinePlayers();
|
||||
|
||||
// END server software specific section -- all code below does not use any code outside of this class / Java
|
||||
|
||||
// Construct the post data
|
||||
StringBuilder json = new StringBuilder(1024);
|
||||
json.append('{');
|
||||
|
||||
// The plugin's description file containg all of the plugin data such as name, version, author, etc
|
||||
appendJSONPair(json, "guid", guid);
|
||||
appendJSONPair(json, "plugin_version", pluginVersion);
|
||||
appendJSONPair(json, "server_version", serverVersion);
|
||||
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
|
||||
|
||||
// New data as of R6
|
||||
String osname = System.getProperty("os.name");
|
||||
String osarch = System.getProperty("os.arch");
|
||||
String osversion = System.getProperty("os.version");
|
||||
String java_version = System.getProperty("java.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
// normalize os arch .. amd64 -> x86_64
|
||||
if(osarch.equals("amd64")) {
|
||||
osarch = "x86_64";
|
||||
}
|
||||
|
||||
appendJSONPair(json, "osname", osname);
|
||||
appendJSONPair(json, "osarch", osarch);
|
||||
appendJSONPair(json, "osversion", osversion);
|
||||
appendJSONPair(json, "cores", Integer.toString(coreCount));
|
||||
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
|
||||
appendJSONPair(json, "java_version", java_version);
|
||||
|
||||
// If we're pinging, append it
|
||||
if(isPing) {
|
||||
appendJSONPair(json, "ping", "1");
|
||||
}
|
||||
|
||||
if(graphs.size() > 0) {
|
||||
synchronized(graphs) {
|
||||
json.append(',');
|
||||
json.append('"');
|
||||
json.append("graphs");
|
||||
json.append('"');
|
||||
json.append(':');
|
||||
json.append('{');
|
||||
|
||||
boolean firstGraph = true;
|
||||
|
||||
final Iterator<Graph> iter = graphs.iterator();
|
||||
|
||||
while(iter.hasNext()) {
|
||||
Graph graph = iter.next();
|
||||
|
||||
StringBuilder graphJson = new StringBuilder();
|
||||
graphJson.append('{');
|
||||
|
||||
for(Plotter plotter : graph.getPlotters()) {
|
||||
appendJSONPair(graphJson, plotter.getColumnName(), Integer.toString(plotter.getValue()));
|
||||
}
|
||||
|
||||
graphJson.append('}');
|
||||
|
||||
if(!firstGraph) {
|
||||
json.append(',');
|
||||
}
|
||||
|
||||
json.append(escapeJSON(graph.getName()));
|
||||
json.append(':');
|
||||
json.append(graphJson);
|
||||
|
||||
firstGraph = false;
|
||||
}
|
||||
|
||||
json.append('}');
|
||||
}
|
||||
}
|
||||
|
||||
// close json
|
||||
json.append('}');
|
||||
|
||||
// Create the url
|
||||
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
|
||||
|
||||
// Connect to the website
|
||||
URLConnection connection;
|
||||
|
||||
// Mineshafter creates a socks proxy, so we can safely bypass it
|
||||
// It does not reroute POST requests so we need to go around it
|
||||
if(isMineshafterPresent()) {
|
||||
connection = url.openConnection(Proxy.NO_PROXY);
|
||||
} else {
|
||||
connection = url.openConnection();
|
||||
}
|
||||
|
||||
|
||||
byte[] uncompressed = json.toString().getBytes();
|
||||
byte[] compressed = gzip(json.toString());
|
||||
|
||||
// Headers
|
||||
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
|
||||
connection.addRequestProperty("Content-Type", "application/json");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
|
||||
connection.setDoOutput(true);
|
||||
|
||||
if(debug) {
|
||||
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
|
||||
}
|
||||
|
||||
// Write the data
|
||||
OutputStream os = connection.getOutputStream();
|
||||
os.write(compressed);
|
||||
os.flush();
|
||||
|
||||
// Now read the response
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String response = reader.readLine();
|
||||
|
||||
// close resources
|
||||
os.close();
|
||||
reader.close();
|
||||
|
||||
if(response == null || response.startsWith("ERR") || response.startsWith("7")) {
|
||||
if(response == null) {
|
||||
response = "null";
|
||||
} else if(response.startsWith("7")) {
|
||||
response = response.substring(response.startsWith("7,") ? 2 : 1);
|
||||
}
|
||||
|
||||
throw new IOException(response);
|
||||
} else {
|
||||
// Is this the first update this hour?
|
||||
if(response.equals("1") || response.contains("This is your first update this hour")) {
|
||||
synchronized(graphs) {
|
||||
final Iterator<Graph> iter = graphs.iterator();
|
||||
|
||||
while(iter.hasNext()) {
|
||||
final Graph graph = iter.next();
|
||||
|
||||
for(Plotter plotter : graph.getPlotters()) {
|
||||
plotter.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GZip compress a string of bytes
|
||||
*/
|
||||
public static byte[] gzip(String input) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzos = null;
|
||||
|
||||
try {
|
||||
gzos = new GZIPOutputStream(baos);
|
||||
gzos.write(input.getBytes("UTF-8"));
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(gzos != null) try {
|
||||
gzos.close();
|
||||
} catch(IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
|
||||
* @return true if mineshafter is installed on the server
|
||||
*/
|
||||
private boolean isMineshafterPresent() {
|
||||
try {
|
||||
Class.forName("mineshafter.MineServer");
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a json encoded key/value pair to the given string builder.
|
||||
*/
|
||||
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
|
||||
boolean isValueNumeric = false;
|
||||
|
||||
try {
|
||||
if(value.equals("0") || !value.endsWith("0")) {
|
||||
Double.parseDouble(value);
|
||||
isValueNumeric = true;
|
||||
}
|
||||
} catch(NumberFormatException e) {
|
||||
isValueNumeric = false;
|
||||
}
|
||||
|
||||
if(json.charAt(json.length() - 1) != '{') {
|
||||
json.append(',');
|
||||
}
|
||||
|
||||
json.append(escapeJSON(key));
|
||||
json.append(':');
|
||||
|
||||
if(isValueNumeric) {
|
||||
json.append(value);
|
||||
} else {
|
||||
json.append(escapeJSON(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a string to create a valid JSON string
|
||||
*/
|
||||
private static String escapeJSON(String text) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append('"');
|
||||
for(int index = 0; index < text.length(); index++) {
|
||||
char chr = text.charAt(index);
|
||||
|
||||
switch(chr) {
|
||||
case '"':
|
||||
case '\\':
|
||||
builder.append('\\');
|
||||
builder.append(chr);
|
||||
break;
|
||||
case '\b':
|
||||
builder.append("\\b");
|
||||
break;
|
||||
case '\t':
|
||||
builder.append("\\t");
|
||||
break;
|
||||
case '\n':
|
||||
builder.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
builder.append("\\r");
|
||||
break;
|
||||
default:
|
||||
if(chr < ' ') {
|
||||
String t = "000" + Integer.toHexString(chr);
|
||||
builder.append("\\u" + t.substring(t.length() - 4));
|
||||
} else {
|
||||
builder.append(chr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.append('"');
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode text as UTF-8
|
||||
* @param text the text to encode
|
||||
* @return the encoded text, as UTF-8
|
||||
*/
|
||||
private static String urlEncode(final String text) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(text, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom graph on the website
|
||||
*/
|
||||
public static class Graph {
|
||||
|
||||
/**
|
||||
* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
|
||||
* rejected
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The set of plotters that are contained within this graph
|
||||
*/
|
||||
private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
|
||||
|
||||
private Graph(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the graph's name
|
||||
* @return the Graph's name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plotter to the graph, which will be used to plot entries
|
||||
* @param plotter the plotter to add to the graph
|
||||
*/
|
||||
public void addPlotter(final Plotter plotter) {
|
||||
plotters.add(plotter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a plotter from the graph
|
||||
* @param plotter the plotter to remove from the graph
|
||||
*/
|
||||
public void removePlotter(final Plotter plotter) {
|
||||
plotters.remove(plotter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
|
||||
* @return an unmodifiable {@link java.util.Set} of the plotter objects
|
||||
*/
|
||||
public Set<Plotter> getPlotters() {
|
||||
return Collections.unmodifiableSet(plotters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if(!(object instanceof Graph)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Graph graph = (Graph)object;
|
||||
return graph.name.equals(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the server owner decides to opt-out of BukkitMetrics while the server is running.
|
||||
*/
|
||||
protected void onOptOut() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used to collect custom data for a plugin
|
||||
*/
|
||||
public static abstract class Plotter {
|
||||
|
||||
/**
|
||||
* The plot's name
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Construct a plotter with the default plot name
|
||||
*/
|
||||
public Plotter() {
|
||||
this("Default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a plotter with a specific plot name
|
||||
* @param name the name of the plotter to use, which will show up on the website
|
||||
*/
|
||||
public Plotter(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value for the plotted point. Since this function defers to an external function it may or may
|
||||
* not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called
|
||||
* from any thread so care should be taken when accessing resources that need to be synchronized.
|
||||
* @return the current value for the point to be plotted.
|
||||
*/
|
||||
public abstract int getValue();
|
||||
|
||||
/**
|
||||
* Get the column name for the plotted point
|
||||
* @return the plotted point's column name
|
||||
*/
|
||||
public String getColumnName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the website graphs have been updated
|
||||
*/
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getColumnName().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if(!(object instanceof Plotter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Plotter plotter = (Plotter)object;
|
||||
return plotter.name.equals(name) && plotter.getValue() == getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,750 +0,0 @@
|
||||
package me.wiefferink.areashop.lib;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* Check for updates on BukkitDev for a given plugin, and download the updates if needed.
|
||||
* <p/>
|
||||
* <b>VERY, VERY IMPORTANT</b>: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
|
||||
* <br>
|
||||
* It is a <b>BUKKIT POLICY</b> that you include a boolean value in your config that prevents the auto-updater from running <b>AT ALL</b>.
|
||||
* <br>
|
||||
* If you fail to include this option in your config, your plugin will be <b>REJECTED</b> when you attempt to submit it to dev.bukkit.org.
|
||||
* <p/>
|
||||
* An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
|
||||
* <br>
|
||||
* If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
|
||||
*
|
||||
* @author Gravity
|
||||
* @version 2.3
|
||||
*/
|
||||
|
||||
public class Updater {
|
||||
|
||||
/* Constants */
|
||||
|
||||
// Remote file's title
|
||||
private static final String TITLE_VALUE = "name";
|
||||
// Remote file's download link
|
||||
private static final String LINK_VALUE = "downloadUrl";
|
||||
// Remote file's release type
|
||||
private static final String TYPE_VALUE = "releaseType";
|
||||
// Remote file's build version
|
||||
private static final String VERSION_VALUE = "gameVersion";
|
||||
// Path to GET
|
||||
private static final String QUERY = "/servermods/files?projectIds=";
|
||||
// Slugs will be appended to this to get to the project's RSS feed
|
||||
private static final String HOST = "https://api.curseforge.com";
|
||||
// User-agent when querying Curse
|
||||
private static final String USER_AGENT = "Updater (by Gravity)";
|
||||
// Used for locating version numbers in file names
|
||||
private static final String DELIMETER = "^V|[\\s_-]V";
|
||||
// If the version number contains one of these, don't update.
|
||||
private static final String[] NO_UPDATE_TAG = { "-DEV", "-PRE", "-SNAPSHOT" };
|
||||
// Used for downloading files
|
||||
private static final int BYTE_SIZE = 1024;
|
||||
// Config key for api key
|
||||
private static final String API_KEY_CONFIG_KEY = "api-key";
|
||||
// Config key for disabling Updater
|
||||
private static final String DISABLE_CONFIG_KEY = "disable";
|
||||
// Default api key value in config
|
||||
private static final String API_KEY_DEFAULT = "PUT_API_KEY_HERE";
|
||||
// Default disable value in config
|
||||
private static final boolean DISABLE_DEFAULT = false;
|
||||
|
||||
/* User-provided variables */
|
||||
|
||||
// Plugin running Updater
|
||||
private final Plugin plugin;
|
||||
// Type of update check to run
|
||||
private final UpdateType type;
|
||||
// Whether to announce file downloads
|
||||
private final boolean announce;
|
||||
// The plugin file (jar)
|
||||
private final File file;
|
||||
// The folder that downloads will be placed in
|
||||
private final File updateFolder;
|
||||
// The provided callback (if any)
|
||||
private final UpdateCallback callback;
|
||||
// Project's Curse ID
|
||||
private int id = -1;
|
||||
// BukkitDev ServerMods API key
|
||||
private String apiKey = null;
|
||||
|
||||
/* Collected from Curse API */
|
||||
|
||||
private String versionName;
|
||||
private String versionLink;
|
||||
private String versionType;
|
||||
private String versionGameVersion;
|
||||
|
||||
/* Update process variables */
|
||||
|
||||
// Connection to RSS
|
||||
private URL url;
|
||||
// Updater thread
|
||||
private Thread thread;
|
||||
// Used for determining the outcome of the update process
|
||||
private Updater.UpdateResult result = Updater.UpdateResult.SUCCESS;
|
||||
|
||||
/**
|
||||
* Gives the developer the result of the update process. Can be obtained by called {@link #getResult()}
|
||||
*/
|
||||
public enum UpdateResult {
|
||||
/**
|
||||
* The updater found an update, and has readied it to be loaded the next time the server restarts/reloads.
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* The updater did not find an update, and nothing was downloaded.
|
||||
*/
|
||||
NO_UPDATE,
|
||||
/**
|
||||
* The server administrator has disabled the updating system.
|
||||
*/
|
||||
DISABLED,
|
||||
/**
|
||||
* The updater found an update, but was unable to download it.
|
||||
*/
|
||||
FAIL_DOWNLOAD,
|
||||
/**
|
||||
* For some reason, the updater was unable to contact dev.bukkit.org to download the file.
|
||||
*/
|
||||
FAIL_DBO,
|
||||
/**
|
||||
* When running the version check, the file on DBO did not contain a recognizable version.
|
||||
*/
|
||||
FAIL_NOVERSION,
|
||||
/**
|
||||
* The id provided by the plugin running the updater was invalid and doesn't exist on DBO.
|
||||
*/
|
||||
FAIL_BADID,
|
||||
/**
|
||||
* The server administrator has improperly configured their API key in the configuration.
|
||||
*/
|
||||
FAIL_APIKEY,
|
||||
/**
|
||||
* The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.
|
||||
*/
|
||||
UPDATE_AVAILABLE
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the developer to specify the type of update that will be run.
|
||||
*/
|
||||
public enum UpdateType {
|
||||
/**
|
||||
* Run a version check, and then if the file is out of date, download the newest version.
|
||||
*/
|
||||
DEFAULT,
|
||||
/**
|
||||
* Don't run a version check, just find the latest update and download it.
|
||||
*/
|
||||
NO_VERSION_CHECK,
|
||||
/**
|
||||
* Get information about the version and the download size, but don't actually download anything.
|
||||
*/
|
||||
NO_DOWNLOAD
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the various release types of a file on BukkitDev.
|
||||
*/
|
||||
public enum ReleaseType {
|
||||
/**
|
||||
* An "alpha" file.
|
||||
*/
|
||||
ALPHA,
|
||||
/**
|
||||
* A "beta" file.
|
||||
*/
|
||||
BETA,
|
||||
/**
|
||||
* A "release" file.
|
||||
*/
|
||||
RELEASE
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the updater.
|
||||
*
|
||||
* @param plugin The plugin that is checking for an update.
|
||||
* @param id The dev.bukkit.org id of the project.
|
||||
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||
* @param announce True if the program should announce the progress of new updates in console.
|
||||
*/
|
||||
public Updater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
|
||||
this(plugin, id, file, type, null, announce);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the updater with the provided callback.
|
||||
*
|
||||
* @param plugin The plugin that is checking for an update.
|
||||
* @param id The dev.bukkit.org id of the project.
|
||||
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||
* @param callback The callback instance to notify when the Updater has finished
|
||||
*/
|
||||
public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback) {
|
||||
this(plugin, id, file, type, callback, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the updater with the provided callback.
|
||||
*
|
||||
* @param plugin The plugin that is checking for an update.
|
||||
* @param id The dev.bukkit.org id of the project.
|
||||
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||
* @param callback The callback instance to notify when the Updater has finished
|
||||
* @param announce True if the program should announce the progress of new updates in console.
|
||||
*/
|
||||
public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback, boolean announce) {
|
||||
this.plugin = plugin;
|
||||
this.type = type;
|
||||
this.announce = announce;
|
||||
this.file = file;
|
||||
this.id = id;
|
||||
this.updateFolder = this.plugin.getServer().getUpdateFolderFile();
|
||||
this.callback = callback;
|
||||
|
||||
final File pluginFile = this.plugin.getDataFolder().getParentFile();
|
||||
final File updaterFile = new File(pluginFile, "Updater");
|
||||
final File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n'
|
||||
+ "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n'
|
||||
+ "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration.");
|
||||
config.addDefault(API_KEY_CONFIG_KEY, API_KEY_DEFAULT);
|
||||
config.addDefault(DISABLE_CONFIG_KEY, DISABLE_DEFAULT);
|
||||
|
||||
if (!updaterFile.exists()) {
|
||||
this.fileIOOrError(updaterFile, updaterFile.mkdir(), true);
|
||||
}
|
||||
|
||||
boolean createFile = !updaterConfigFile.exists();
|
||||
try {
|
||||
if (createFile) {
|
||||
this.fileIOOrError(updaterConfigFile, updaterConfigFile.createNewFile(), true);
|
||||
config.options().copyDefaults(true);
|
||||
config.save(updaterConfigFile);
|
||||
} else {
|
||||
config.load(updaterConfigFile);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
final String message;
|
||||
if (createFile) {
|
||||
message = "The updater could not create configuration at " + updaterFile.getAbsolutePath();
|
||||
} else {
|
||||
message = "The updater could not load configuration at " + updaterFile.getAbsolutePath();
|
||||
}
|
||||
this.plugin.getLogger().log(Level.SEVERE, message, e);
|
||||
}
|
||||
|
||||
if (config.getBoolean(DISABLE_CONFIG_KEY)) {
|
||||
this.result = UpdateResult.DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
String key = config.getString(API_KEY_CONFIG_KEY);
|
||||
if (API_KEY_DEFAULT.equalsIgnoreCase(key) || "".equals(key)) {
|
||||
key = null;
|
||||
}
|
||||
|
||||
this.apiKey = key;
|
||||
|
||||
try {
|
||||
this.url = new URL(Updater.HOST + Updater.QUERY + this.id);
|
||||
} catch (final MalformedURLException e) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, "The project ID provided for updating, " + this.id + " is invalid.", e);
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
}
|
||||
|
||||
if (this.result != UpdateResult.FAIL_BADID) {
|
||||
this.thread = new Thread(new UpdateRunnable());
|
||||
this.thread.start();
|
||||
} else {
|
||||
runUpdater();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result of the update process.
|
||||
*
|
||||
* @return result of the update process.
|
||||
* @see UpdateResult
|
||||
*/
|
||||
public Updater.UpdateResult getResult() {
|
||||
this.waitForThread();
|
||||
return this.result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest version's release type.
|
||||
*
|
||||
* @return latest version's release type.
|
||||
* @see ReleaseType
|
||||
*/
|
||||
public ReleaseType getLatestType() {
|
||||
this.waitForThread();
|
||||
if (this.versionType != null) {
|
||||
for (ReleaseType type : ReleaseType.values()) {
|
||||
if (this.versionType.equalsIgnoreCase(type.name())) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest version's game version (such as "CB 1.2.5-R1.0").
|
||||
*
|
||||
* @return latest version's game version.
|
||||
*/
|
||||
public String getLatestGameVersion() {
|
||||
this.waitForThread();
|
||||
return this.versionGameVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest version's name (such as "Project v1.0").
|
||||
*
|
||||
* @return latest version's name.
|
||||
*/
|
||||
public String getLatestName() {
|
||||
this.waitForThread();
|
||||
return this.versionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest version's direct file link.
|
||||
*
|
||||
* @return latest version's file link.
|
||||
*/
|
||||
public String getLatestFileLink() {
|
||||
this.waitForThread();
|
||||
return this.versionLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* As the result of Updater output depends on the thread's completion, it is necessary to wait for the thread to finish
|
||||
* before allowing anyone to check the result.
|
||||
*/
|
||||
private void waitForThread() {
|
||||
if ((this.thread != null) && this.thread.isAlive()) {
|
||||
try {
|
||||
this.thread.join();
|
||||
} catch (final InterruptedException e) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an update from dev.bukkit.org into the server's update folder.
|
||||
*
|
||||
* @param file the name of the file to save it as.
|
||||
*/
|
||||
private void saveFile(String file) {
|
||||
final File folder = this.updateFolder;
|
||||
|
||||
deleteOldFiles();
|
||||
if (!folder.exists()) {
|
||||
this.fileIOOrError(folder, folder.mkdir(), true);
|
||||
}
|
||||
downloadFile();
|
||||
|
||||
// Check to see if it's a zip file, if it is, unzip it.
|
||||
final File dFile = new File(folder.getAbsolutePath(), file);
|
||||
if (dFile.getName().endsWith(".zip")) {
|
||||
// Unzip
|
||||
this.unzip(dFile.getAbsolutePath());
|
||||
}
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("Finished updating.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a file and save it to the specified folder.
|
||||
*/
|
||||
private void downloadFile() {
|
||||
BufferedInputStream in = null;
|
||||
FileOutputStream fout = null;
|
||||
try {
|
||||
URL fileUrl = new URL(this.versionLink);
|
||||
final int fileLength = fileUrl.openConnection().getContentLength();
|
||||
in = new BufferedInputStream(fileUrl.openStream());
|
||||
fout = new FileOutputStream(new File(this.updateFolder, file.getName()));
|
||||
|
||||
final byte[] data = new byte[Updater.BYTE_SIZE];
|
||||
int count;
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
|
||||
}
|
||||
long downloaded = 0;
|
||||
while ((count = in.read(data, 0, Updater.BYTE_SIZE)) != -1) {
|
||||
downloaded += count;
|
||||
fout.write(data, 0, count);
|
||||
final int percent = (int) ((downloaded * 100) / fileLength);
|
||||
if (this.announce && ((percent % 10) == 0)) {
|
||||
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
this.plugin.getLogger().log(Level.WARNING, "The auto-updater tried to download a new update, but was unsuccessful.", ex);
|
||||
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
if (fout != null) {
|
||||
fout.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove possibly leftover files from the update folder.
|
||||
*/
|
||||
private void deleteOldFiles() {
|
||||
//Just a quick check to make sure we didn't leave any files from last time...
|
||||
File[] list = listFilesOrError(this.updateFolder);
|
||||
for (final File xFile : list) {
|
||||
if (xFile.getName().endsWith(".zip")) {
|
||||
this.fileIOOrError(xFile, xFile.mkdir(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of Zip-File-Extractor, modified by Gravity for use with Updater.
|
||||
*
|
||||
* @param file the location of the file to extract.
|
||||
*/
|
||||
private void unzip(String file) {
|
||||
final File fSourceZip = new File(file);
|
||||
try {
|
||||
final String zipPath = file.substring(0, file.length() - 4);
|
||||
ZipFile zipFile = new ZipFile(fSourceZip);
|
||||
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = e.nextElement();
|
||||
File destinationFilePath = new File(zipPath, entry.getName());
|
||||
this.fileIOOrError(destinationFilePath.getParentFile(), destinationFilePath.getParentFile().mkdirs(), true);
|
||||
if (!entry.isDirectory()) {
|
||||
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
int b;
|
||||
final byte[] buffer = new byte[Updater.BYTE_SIZE];
|
||||
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos, Updater.BYTE_SIZE);
|
||||
while ((b = bis.read(buffer, 0, Updater.BYTE_SIZE)) != -1) {
|
||||
bos.write(buffer, 0, b);
|
||||
}
|
||||
bos.flush();
|
||||
bos.close();
|
||||
bis.close();
|
||||
final String name = destinationFilePath.getName();
|
||||
if (name.endsWith(".jar") && this.pluginExists(name)) {
|
||||
File output = new File(this.updateFolder, name);
|
||||
this.fileIOOrError(output, destinationFilePath.renameTo(output), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
zipFile.close();
|
||||
|
||||
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
|
||||
moveNewZipFiles(zipPath);
|
||||
|
||||
} catch (final IOException e) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, "The auto-updater tried to unzip a new update file, but was unsuccessful.", e);
|
||||
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
|
||||
} finally {
|
||||
this.fileIOOrError(fSourceZip, fSourceZip.delete(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find any new files extracted from an update into the plugin's data directory.
|
||||
* @param zipPath path of extracted files.
|
||||
*/
|
||||
private void moveNewZipFiles(String zipPath) {
|
||||
File[] list = listFilesOrError(new File(zipPath));
|
||||
for (final File dFile : list) {
|
||||
if (dFile.isDirectory() && this.pluginExists(dFile.getName())) {
|
||||
// Current dir
|
||||
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName());
|
||||
// List of existing files in the new dir
|
||||
final File[] dList = listFilesOrError(dFile);
|
||||
// List of existing files in the current dir
|
||||
final File[] oList = listFilesOrError(oFile);
|
||||
for (File cFile : dList) {
|
||||
// Loop through all the files in the new dir
|
||||
boolean found = false;
|
||||
for (final File xFile : oList) {
|
||||
// Loop through all the contents in the current dir to see if it exists
|
||||
if (xFile.getName().equals(cFile.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Move the new file into the current dir
|
||||
File output = new File(oFile, cFile.getName());
|
||||
this.fileIOOrError(output, cFile.renameTo(output), true);
|
||||
} else {
|
||||
// This file already exists, so we don't need it anymore.
|
||||
this.fileIOOrError(cFile, cFile.delete(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.fileIOOrError(dFile, dFile.delete(), false);
|
||||
}
|
||||
File zip = new File(zipPath);
|
||||
this.fileIOOrError(zip, zip.delete(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
|
||||
*
|
||||
* @param name a name to check for inside the plugins folder.
|
||||
* @return true if a file inside the plugins folder is named this.
|
||||
*/
|
||||
private boolean pluginExists(String name) {
|
||||
File[] plugins = listFilesOrError(new File("plugins"));
|
||||
for (final File file : plugins) {
|
||||
if (file.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the program should continue by evaluating whether the plugin is already updated, or shouldn't be updated.
|
||||
*
|
||||
* @return true if the version was located and is not the same as the remote's newest.
|
||||
*/
|
||||
private boolean versionCheck() {
|
||||
final String title = this.versionName;
|
||||
if (this.type != UpdateType.NO_VERSION_CHECK) {
|
||||
String localVersion = this.plugin.getDescription().getVersion();
|
||||
if(localVersion.contains("#")) { // Strip build number
|
||||
localVersion = localVersion.substring(0, localVersion.indexOf("#"));
|
||||
}
|
||||
if (title.split(DELIMETER).length == 2) {
|
||||
// Get the newest file's version number
|
||||
final String remoteVersion = title.split(DELIMETER)[1].split(" ")[0];
|
||||
|
||||
if (this.hasTag(localVersion) || !this.shouldUpdate(localVersion, remoteVersion)) {
|
||||
// We already have the latest version, or this build is tagged for no-update
|
||||
this.result = Updater.UpdateResult.NO_UPDATE;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// The file's name did not contain the string 'vVersion'
|
||||
final String authorInfo = this.plugin.getDescription().getAuthors().isEmpty() ? "" : " (" + this.plugin.getDescription().getAuthors().get(0) + ")";
|
||||
this.plugin.getLogger().warning("The author of this plugin" + authorInfo + " has misconfigured their Auto Update system");
|
||||
this.plugin.getLogger().warning("File versions should follow the format 'PluginName vVERSION'");
|
||||
this.plugin.getLogger().warning("Please notify the author of this error.");
|
||||
this.result = Updater.UpdateResult.FAIL_NOVERSION;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>If you wish to run mathematical versioning checks, edit this method.</b>
|
||||
* <p>
|
||||
* With default behavior, Updater will NOT verify that a remote version available on BukkitDev
|
||||
* which is not this version is indeed an "update".
|
||||
* If a version is present on BukkitDev that is not the version that is currently running,
|
||||
* Updater will assume that it is a newer version.
|
||||
* This is because there is no standard versioning scheme, and creating a calculation that can
|
||||
* determine whether a new update is actually an update is sometimes extremely complicated.
|
||||
* </p>
|
||||
* <p>
|
||||
* Updater will call this method from {@link #versionCheck()} before deciding whether
|
||||
* the remote version is actually an update.
|
||||
* If you have a specific versioning scheme with which a mathematical determination can
|
||||
* be reliably made to decide whether one version is higher than another, you may
|
||||
* revise this method, using the local and remote version parameters, to execute the
|
||||
* appropriate check.
|
||||
* </p>
|
||||
* <p>
|
||||
* Returning a value of <b>false</b> will tell the update process that this is NOT a new version.
|
||||
* Without revision, this method will always consider a remote version at all different from
|
||||
* that of the local version a new update.
|
||||
* </p>
|
||||
* @param localVersion the current version
|
||||
* @param remoteVersion the remote version
|
||||
* @return true if Updater should consider the remote version an update, false if not.
|
||||
*/
|
||||
public boolean shouldUpdate(String localVersion, String remoteVersion) {
|
||||
return !localVersion.equalsIgnoreCase(remoteVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate whether the version number is marked showing that it should not be updated by this program.
|
||||
*
|
||||
* @param version a version number to check for tags in.
|
||||
* @return true if updating should be disabled.
|
||||
*/
|
||||
private boolean hasTag(String version) {
|
||||
for (final String string : Updater.NO_UPDATE_TAG) {
|
||||
if (version.contains(string)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a connection to the BukkitDev API and request the newest file's details.
|
||||
*
|
||||
* @return true if successful.
|
||||
*/
|
||||
private boolean read() {
|
||||
try {
|
||||
final URLConnection conn = this.url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
|
||||
if (this.apiKey != null) {
|
||||
conn.addRequestProperty("X-API-Key", this.apiKey);
|
||||
}
|
||||
conn.addRequestProperty("User-Agent", Updater.USER_AGENT);
|
||||
|
||||
conn.setDoOutput(true);
|
||||
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
final String response = reader.readLine();
|
||||
|
||||
final JSONArray array = (JSONArray) JSONValue.parse(response);
|
||||
|
||||
if (array.isEmpty()) {
|
||||
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
return false;
|
||||
}
|
||||
|
||||
JSONObject latestUpdate = (JSONObject) array.get(array.size() - 1);
|
||||
this.versionName = (String) latestUpdate.get(Updater.TITLE_VALUE);
|
||||
this.versionLink = (String) latestUpdate.get(Updater.LINK_VALUE);
|
||||
this.versionType = (String) latestUpdate.get(Updater.TYPE_VALUE);
|
||||
this.versionGameVersion = (String) latestUpdate.get(Updater.VERSION_VALUE);
|
||||
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
if(e.getMessage() != null && e.getMessage().contains("HTTP response code: 403")) {
|
||||
this.plugin.getLogger().severe("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
|
||||
this.plugin.getLogger().severe("Please double-check your configuration to ensure it is correct.");
|
||||
this.result = UpdateResult.FAIL_APIKEY;
|
||||
} else {
|
||||
this.plugin.getLogger().severe("The updater could not contact dev.bukkit.org for updating.");
|
||||
this.plugin.getLogger().severe("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||
this.result = UpdateResult.FAIL_DBO;
|
||||
}
|
||||
AreaShop.debug(ExceptionUtils.getStackTrace(e));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a file operation and log any errors if it fails.
|
||||
* @param file file operation is performed on.
|
||||
* @param result result of file operation.
|
||||
* @param create true if a file is being created, false if deleted.
|
||||
*/
|
||||
private void fileIOOrError(File file, boolean result, boolean create) {
|
||||
if (!result) {
|
||||
this.plugin.getLogger().severe("The updater could not " + (create ? "create" : "delete") + " file at: " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private File[] listFilesOrError(File folder) {
|
||||
File[] contents = folder.listFiles();
|
||||
if (contents == null) {
|
||||
this.plugin.getLogger().severe("The updater could not access files at: " + this.updateFolder.getAbsolutePath());
|
||||
return new File[0];
|
||||
} else {
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on main thread when the Updater has finished working, regardless
|
||||
* of result.
|
||||
*/
|
||||
public interface UpdateCallback {
|
||||
/**
|
||||
* Called when the updater has finished working.
|
||||
* @param updater The updater instance
|
||||
*/
|
||||
void onFinish(Updater updater);
|
||||
}
|
||||
|
||||
private class UpdateRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
runUpdater();
|
||||
}
|
||||
}
|
||||
|
||||
private void runUpdater() {
|
||||
if (this.url != null && (this.read() && this.versionCheck())) {
|
||||
// Obtain the results of the project's file feed
|
||||
if ((this.versionLink != null) && (this.type != UpdateType.NO_DOWNLOAD)) {
|
||||
String name = this.file.getName();
|
||||
// If it's a zip file, it shouldn't be downloaded as the plugin's name
|
||||
if (this.versionLink.endsWith(".zip")) {
|
||||
name = this.versionLink.substring(this.versionLink.lastIndexOf("/") + 1);
|
||||
}
|
||||
this.saveFile(name);
|
||||
} else {
|
||||
this.result = UpdateResult.UPDATE_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.callback != null) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runCallback();
|
||||
}
|
||||
}.runTask(this.plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void runCallback() {
|
||||
this.callback.onFinish(this);
|
||||
}
|
||||
}
|
||||
+112
-117
@@ -1,9 +1,11 @@
|
||||
package me.wiefferink.areashop.listeners;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.regions.TransactionalRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -12,129 +14,122 @@ import org.bukkit.event.player.PlayerKickEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Checks for placement of signs for this plugin
|
||||
* @author NLThijs48
|
||||
* Notify region expiry and track activity time.
|
||||
*/
|
||||
public final class PlayerLoginLogoutListener implements Listener {
|
||||
private AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public PlayerLoginLogoutListener(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a sign is changed
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
if(event.getResult() != Result.ALLOWED) {
|
||||
return;
|
||||
}
|
||||
final Player player = event.getPlayer();
|
||||
// Notify admins for plugin updates
|
||||
if(plugin.updateAvailable() && player.hasPermission("areashop.notifyupdate")) {
|
||||
AreaShop.getInstance().message(player, "update-playerNotify", AreaShop.getInstance().getDescription().getVersion(), AreaShop.getInstance().getUpdater().getLatestName());
|
||||
}
|
||||
// Schedule task to check for notifications, prevents a lag spike at login
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Delay until all regions are loaded
|
||||
if(!plugin.isReady()) {
|
||||
return;
|
||||
}
|
||||
if(!player.isOnline()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
// Notify for rents that almost run out
|
||||
for(RentRegion region : plugin.getFileManager().getRents()) {
|
||||
if(region.isRenter(player)) {
|
||||
String warningSetting = region.getStringSetting("rent.warningOnLoginTime");
|
||||
if(warningSetting == null || warningSetting.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
long warningTime = Utils.durationStringToLong(warningSetting);
|
||||
if(region.getTimeLeft() < warningTime) {
|
||||
// Send the warning message later to let it appear after general MOTD messages
|
||||
AreaShop.getInstance().message(player, "rent-expireWarning", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
}.runTaskTimer(plugin, 25, 25);
|
||||
// Check if the player has regions that use an old name of him and update them
|
||||
final List<GeneralRegion> regions = new ArrayList<>(plugin.getFileManager().getRegions());
|
||||
new BukkitRunnable() {
|
||||
private int current = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Delay until all regions are loaded
|
||||
if(!plugin.isReady()) {
|
||||
return;
|
||||
}
|
||||
// Check all regions
|
||||
for(int i=0; i<plugin.getConfig().getInt("nameupdate.regionsPerTick"); i++) {
|
||||
if(current < regions.size()) {
|
||||
GeneralRegion region = regions.get(current);
|
||||
if(region.isOwner(player)) {
|
||||
if(region.isBuyRegion()) {
|
||||
if(!player.getName().equals(region.getStringSetting("buy.buyerName"))) {
|
||||
region.setSetting("buy.buyerName", player.getName());
|
||||
region.update();
|
||||
}
|
||||
} else if(region.isRentRegion()) {
|
||||
if(!player.getName().equals(region.getStringSetting("rent.renterName"))) {
|
||||
region.setSetting("rent.renterName", player.getName());
|
||||
region.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
current++;
|
||||
}
|
||||
}
|
||||
if(current >= regions.size()) {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 22, 1); // Wait a bit before starting to prevent a lot of stress on the server when a player joins (a lot of plugins already do stuff then)
|
||||
}
|
||||
|
||||
// Active time updates
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogout(PlayerQuitEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerKick(PlayerKickEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the last active time for all regions the player is owner off
|
||||
* @param player The player to update the active times for
|
||||
*/
|
||||
private void updateLastActive(Player player) {
|
||||
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
|
||||
if(region.isOwner(player)) {
|
||||
region.updateLastActiveTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
private final AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public PlayerLoginLogoutListener(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a sign is changed.
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
if (event.getResult() != Result.ALLOWED) {
|
||||
return;
|
||||
}
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// Schedule task to check for notifications, prevents a lag spike at login
|
||||
Utils.runCancellingTaskTimer(() -> {
|
||||
// Delay until all regions are loaded
|
||||
if (!plugin.isReady()) {
|
||||
return true;
|
||||
}
|
||||
if (!player.isOnline()) {
|
||||
return false;
|
||||
}
|
||||
// Notify for rents that almost run out
|
||||
for (GeneralRegion generalRegion : plugin.getFileManager().getRegions()) {
|
||||
if (!(generalRegion instanceof RentRegion)) {
|
||||
continue;
|
||||
}
|
||||
final RentRegion region = (RentRegion) generalRegion;
|
||||
if (region.isTransactionHolder(player)) {
|
||||
String warningSetting = region.getStringSetting("rent.warningOnLoginTime");
|
||||
if (warningSetting == null || warningSetting.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
long warningTime = Utils.durationStringToLong(warningSetting);
|
||||
if (region.getTimeLeft() < warningTime) {
|
||||
// Send the warning message later to let it appear after general MOTD messages
|
||||
AreaShop.getInstance().message(player, "rent-expireWarning", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify admins for plugin updates
|
||||
AreaShop.getInstance().notifyUpdate(player);
|
||||
return false;
|
||||
}, 25, 25, false);
|
||||
|
||||
// Check if the player has regions that use an old name of him and update them
|
||||
Utils.runCancellingTaskTimer(() -> {
|
||||
if (!plugin.isReady()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<GeneralRegion> regions = new LinkedList<>();
|
||||
for (GeneralRegion region : plugin.getFileManager().getRegions()) {
|
||||
if (region instanceof TransactionalRegion && ((TransactionalRegion) region).isTransactionHolder(player)) {
|
||||
regions.add(region);
|
||||
}
|
||||
}
|
||||
final String name = player.getName();
|
||||
Utils.runAsBatches(regions,
|
||||
plugin.getConfig().getInt("nameupdate.regionsPerTick"),
|
||||
(region) -> {
|
||||
if (region instanceof BuyRegion || region instanceof RentRegion) {
|
||||
String key = region instanceof BuyRegion ? "buy.buyerName" : "rent.renterName";
|
||||
if (!name.equals(region.getStringSetting("buy.buyerName"))) {
|
||||
region.setSetting(key, player.getName());
|
||||
region.update();
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
return false;
|
||||
}, 22, 10, false);
|
||||
}
|
||||
|
||||
// Active time updates
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogout(PlayerQuitEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerKick(PlayerKickEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the last active time for all regions the player is owner off.
|
||||
*
|
||||
* @param player The player to update the active times for
|
||||
*/
|
||||
private void updateLastActive(Player player) {
|
||||
for (GeneralRegion region : plugin.getFileManager().getRegions()) {
|
||||
if (region instanceof TransactionalRegion && ((TransactionalRegion) region).isTransactionHolder(player)) {
|
||||
region.updateLastActiveTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
package me.wiefferink.areashop.listeners;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.SignsFeature;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
/**
|
||||
* Checks for placement of signs for this plugin
|
||||
* @author NLThijs48
|
||||
*/
|
||||
public final class SignBreakListener implements Listener {
|
||||
private AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public SignBreakListener(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when a block is broken
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSignBreak(BlockBreakEvent event) {
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getBlock();
|
||||
// Check if it is a sign
|
||||
if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) {
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign == null) {
|
||||
return;
|
||||
}
|
||||
// Remove the sign of the rental region if the player has permission
|
||||
if(event.getPlayer().hasPermission("areashop.delsign")) {
|
||||
regionSign.remove();
|
||||
plugin.message(event.getPlayer(), "delsign-success", regionSign.getRegion());
|
||||
} else { // Cancel the breaking of the sign
|
||||
event.setCancelled(true);
|
||||
plugin.message(event.getPlayer(), "delsign-noPermission", regionSign.getRegion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the physics of a block change
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onIndirectSignBreak(BlockPhysicsEvent event){
|
||||
Block block = event.getBlock();
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if(block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN){
|
||||
Sign sign = (Sign)block.getState();
|
||||
Block attachedTo = block.getRelative(((org.bukkit.material.Sign)sign.getData()).getAttachedFace());
|
||||
if(attachedTo.getType() == Material.AIR){
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign != null) {
|
||||
event.setCancelled(true); // Cancel the sign breaking, will create a floating sign but at least it is not disconnected/gone
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,359 +0,0 @@
|
||||
package me.wiefferink.areashop.listeners;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.material.Sign;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Checks for placement of signs for this plugin
|
||||
* @author NLThijs48
|
||||
*/
|
||||
public final class SignChangeListener implements Listener {
|
||||
private AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public SignChangeListener(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a sign is changed
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if(!plugin.isReady()) {
|
||||
plugin.message(player, "general-notReady");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the sign is meant for this plugin
|
||||
if(event.getLine(0).contains(plugin.getConfig().getString("signTags.rent"))) {
|
||||
if(!player.hasPermission("areashop.createrent") && !player.hasPermission("areashop.createrent.member") && !player.hasPermission("areashop.createrent.owner")) {
|
||||
plugin.message(player, "setup-noPermissionRent");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
String fourthLine = event.getLine(3);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getWorldGuard().getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if(secondLine == null || secondLine.length() == 0) {
|
||||
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if(regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for(ProtectedRegion pr : regions) {
|
||||
if(first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if(pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if(pr.getPriority() < candidate.getPriority()) {
|
||||
// Already got the correct one
|
||||
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else if(candidate.getParent() != null && candidate.getParent().equals(pr)) {
|
||||
// Already got the correct one
|
||||
} else {
|
||||
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = fourthLine != null && fourthLine.length() != 0;
|
||||
boolean durationSet = thirdLine != null && thirdLine.length() != 0;
|
||||
// check if all the lines are correct
|
||||
if(secondLine == null || secondLine.length() == 0) {
|
||||
plugin.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if(region == null) {
|
||||
plugin.message(player, "cmd-notRegistered", secondLine);
|
||||
return;
|
||||
}
|
||||
|
||||
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, regionManager.getRegion(secondLine), GeneralRegion.RegionType.RENT);
|
||||
if(addResult == FileManager.AddResult.BLACKLISTED) {
|
||||
plugin.message(player, "setup-blacklisted", secondLine);
|
||||
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
|
||||
plugin.message(player, "setup-alreadyRentSign");
|
||||
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
|
||||
plugin.message(player, "setup-noPermission", secondLine);
|
||||
} else if(thirdLine != null && thirdLine.length() != 0 && !Utils.checkTimeFormat(thirdLine)) {
|
||||
plugin.message(player, "setup-wrongDuration");
|
||||
} else {
|
||||
double price = 0.0;
|
||||
if(priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(fourthLine);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add rent to the FileManager
|
||||
final RentRegion rent = new RentRegion(plugin, secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = plugin.getWorldGuardHandler().containsMember(rent.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(rent.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createrent")
|
||||
&& ((player.hasPermission("areashop.createrent.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createrent.member") && isMember)));
|
||||
|
||||
if(landlord) {
|
||||
rent.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if(priceSet) {
|
||||
rent.setPrice(price);
|
||||
}
|
||||
if(durationSet) {
|
||||
rent.setDuration(thirdLine);
|
||||
}
|
||||
Sign sign = (Sign)event.getBlock().getState().getData();
|
||||
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null);
|
||||
|
||||
// Run commands
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
|
||||
plugin.getFileManager().addRent(rent);
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
plugin.message(player, "setup-rentSuccess", rent);
|
||||
// Update the region after the event has written its lines
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
rent.update();
|
||||
}
|
||||
}.runTaskLater(plugin, 1);
|
||||
// Run commands
|
||||
rent.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
}
|
||||
} else if (event.getLine(0).contains(plugin.getConfig().getString("signTags.buy"))) {
|
||||
// Check for permission
|
||||
if(!player.hasPermission("areashop.createbuy") && !player.hasPermission("areashop.createbuy.member") && !player.hasPermission("areashop.createbuy.owner")) {
|
||||
plugin.message(player, "setup-noPermissionBuy");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getWorldGuard().getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if(secondLine == null || secondLine.length() == 0) {
|
||||
Set<ProtectedRegion> regions = plugin.getWorldGuardHandler().getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if(regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for(ProtectedRegion pr : regions) {
|
||||
if(first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if(pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if(pr.getPriority() < candidate.getPriority()) {
|
||||
// Already got the correct one
|
||||
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else if(candidate.getParent() != null && candidate.getParent().equals(pr)) {
|
||||
// Already got the correct one
|
||||
} else {
|
||||
plugin.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = thirdLine != null && thirdLine.length() != 0;
|
||||
// Check if all the lines are correct
|
||||
if(secondLine == null || secondLine.length() == 0) {
|
||||
plugin.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if(region == null) {
|
||||
plugin.message(player, "add-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
FileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, region, GeneralRegion.RegionType.BUY);
|
||||
if(addResult == FileManager.AddResult.BLACKLISTED) {
|
||||
plugin.message(player, "setup-blacklisted", secondLine);
|
||||
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
|
||||
plugin.message(player, "setup-alreadyRentSign");
|
||||
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
|
||||
plugin.message(player, "setup-noPermission", secondLine);
|
||||
} else {
|
||||
double price = 0.0;
|
||||
if(priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(thirdLine);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add buy to the FileManager
|
||||
final BuyRegion buy = new BuyRegion(plugin, secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = plugin.getWorldGuardHandler().containsMember(buy.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = plugin.getWorldGuardHandler().containsOwner(buy.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createbuy")
|
||||
&& ((player.hasPermission("areashop.createbuy.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createbuy.member") && isMember)));
|
||||
|
||||
if(landlord) {
|
||||
buy.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if(priceSet) {
|
||||
buy.setPrice(price);
|
||||
}
|
||||
Sign sign = (Sign)event.getBlock().getState().getData();
|
||||
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null);
|
||||
// Run commands
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, true);
|
||||
|
||||
plugin.getFileManager().addBuy(buy);
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
plugin.message(player, "setup-buySuccess", buy);
|
||||
// Update the region after the event has written its lines
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
buy.update();
|
||||
}
|
||||
}.runTaskLater(plugin, 1);
|
||||
|
||||
// Run commands
|
||||
buy.runEventCommands(GeneralRegion.RegionEvent.CREATED, false);
|
||||
}
|
||||
} else if(event.getLine(0).contains(plugin.getConfig().getString("signTags.add"))) {
|
||||
// Check for permission
|
||||
if(!player.hasPermission("areashop.addsign")) {
|
||||
plugin.message(player, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
GeneralRegion region;
|
||||
if(secondLine != null && secondLine.length() != 0) {
|
||||
// Get region by secondLine of the sign
|
||||
region = plugin.getFileManager().getRegion(secondLine);
|
||||
if(region == null) {
|
||||
plugin.message(player, "add-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getASRegionsInSelection(new CuboidSelection(event.getBlock().getWorld(), event.getBlock().getLocation(), event.getBlock().getLocation()));
|
||||
if(regions.isEmpty()) {
|
||||
plugin.message(player, "addsign-noRegions");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
plugin.message(player, "addsign-couldNotDetectSign", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
Sign sign = (Sign)event.getBlock().getState().getData();
|
||||
if(thirdLine == null || thirdLine.length() == 0) {
|
||||
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null);
|
||||
plugin.message(player, "addsign-success", region);
|
||||
} else {
|
||||
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), thirdLine);
|
||||
plugin.message(player, "addsign-successProfile", thirdLine, region);
|
||||
}
|
||||
|
||||
// Update the region later because this event will do it first
|
||||
final GeneralRegion regionUpdate = region;
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
regionUpdate.update();
|
||||
}
|
||||
}.runTaskLater(plugin, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package me.wiefferink.areashop.listeners;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion.ClickType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class SignClickListener implements Listener {
|
||||
private AreaShop plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public SignClickListener(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSignClick(PlayerInteractEvent event) {
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getClickedBlock();
|
||||
// Check for clicking a sign and rightclicking
|
||||
if((event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)
|
||||
&& (block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN)) {
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if(plugin.getSignlinkerManager().isInSignLinkMode(player)) {
|
||||
return;
|
||||
}
|
||||
// Get the clicktype
|
||||
ClickType clickType = null;
|
||||
if(player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = ClickType.SHIFTLEFTCLICK;
|
||||
} else if(!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = ClickType.LEFTCLICK;
|
||||
} else if(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = ClickType.SHIFTRIGHTCLICK;
|
||||
} else if(!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = ClickType.RIGHTCLICK;
|
||||
}
|
||||
// Run the commands
|
||||
boolean ran = regionSign.runSignCommands(player, clickType);
|
||||
// Only cancel event if at least one command has been executed
|
||||
event.setCancelled(ran);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,39 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.commands.*;
|
||||
import me.wiefferink.areashop.commands.AddCommand;
|
||||
import me.wiefferink.areashop.commands.AddfriendCommand;
|
||||
import me.wiefferink.areashop.commands.AddsignCommand;
|
||||
import me.wiefferink.areashop.commands.BuyCommand;
|
||||
import me.wiefferink.areashop.commands.CommandAreaShop;
|
||||
import me.wiefferink.areashop.commands.DelCommand;
|
||||
import me.wiefferink.areashop.commands.DelfriendCommand;
|
||||
import me.wiefferink.areashop.commands.DelsignCommand;
|
||||
import me.wiefferink.areashop.commands.FindCommand;
|
||||
import me.wiefferink.areashop.commands.GroupaddCommand;
|
||||
import me.wiefferink.areashop.commands.GroupdelCommand;
|
||||
import me.wiefferink.areashop.commands.GroupinfoCommand;
|
||||
import me.wiefferink.areashop.commands.GrouplistCommand;
|
||||
import me.wiefferink.areashop.commands.HelpCommand;
|
||||
import me.wiefferink.areashop.commands.ImportCommand;
|
||||
import me.wiefferink.areashop.commands.InfoCommand;
|
||||
import me.wiefferink.areashop.commands.LinksignsCommand;
|
||||
import me.wiefferink.areashop.commands.MeCommand;
|
||||
import me.wiefferink.areashop.commands.MessageCommand;
|
||||
import me.wiefferink.areashop.commands.ReloadCommand;
|
||||
import me.wiefferink.areashop.commands.RentCommand;
|
||||
import me.wiefferink.areashop.commands.ResellCommand;
|
||||
import me.wiefferink.areashop.commands.SchematiceventCommand;
|
||||
import me.wiefferink.areashop.commands.SellCommand;
|
||||
import me.wiefferink.areashop.commands.SetdurationCommand;
|
||||
import me.wiefferink.areashop.commands.SetlandlordCommand;
|
||||
import me.wiefferink.areashop.commands.SetownerCommand;
|
||||
import me.wiefferink.areashop.commands.SetpriceCommand;
|
||||
import me.wiefferink.areashop.commands.SetrestoreCommand;
|
||||
import me.wiefferink.areashop.commands.SetteleportCommand;
|
||||
import me.wiefferink.areashop.commands.StackCommand;
|
||||
import me.wiefferink.areashop.commands.StopresellCommand;
|
||||
import me.wiefferink.areashop.commands.TeleportCommand;
|
||||
import me.wiefferink.areashop.commands.UnrentCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -12,65 +44,63 @@ import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
private AreaShop plugin;
|
||||
private ArrayList<CommandAreaShop> commands;
|
||||
|
||||
public class CommandManager extends Manager implements CommandExecutor, TabCompleter {
|
||||
private final ArrayList<CommandAreaShop> commands;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
* Constructor.
|
||||
*/
|
||||
public CommandManager(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
public CommandManager() {
|
||||
commands = new ArrayList<>();
|
||||
commands.add(new HelpCommand(plugin));
|
||||
commands.add(new RentCommand(plugin));
|
||||
commands.add(new UnrentCommand(plugin));
|
||||
commands.add(new BuyCommand(plugin));
|
||||
commands.add(new SellCommand(plugin));
|
||||
commands.add(new MeCommand(plugin));
|
||||
commands.add(new InfoCommand(plugin));
|
||||
commands.add(new TeleportCommand(plugin));
|
||||
commands.add(new SetteleportCommand(plugin));
|
||||
commands.add(new AddfriendCommand(plugin));
|
||||
commands.add(new DelfriendCommand(plugin));
|
||||
commands.add(new FindCommand(plugin));
|
||||
commands.add(new ResellCommand(plugin));
|
||||
commands.add(new StopresellCommand(plugin));
|
||||
commands.add(new SetrestoreCommand(plugin));
|
||||
commands.add(new SetpriceCommand(plugin));
|
||||
commands.add(new SetownerCommand(plugin));
|
||||
commands.add(new SetdurationCommand(plugin));
|
||||
commands.add(new ReloadCommand(plugin));
|
||||
commands.add(new GroupaddCommand(plugin));
|
||||
commands.add(new GroupdelCommand(plugin));
|
||||
commands.add(new GrouplistCommand(plugin));
|
||||
commands.add(new GroupinfoCommand(plugin));
|
||||
commands.add(new SchematiceventCommand(plugin));
|
||||
commands.add(new AddCommand(plugin));
|
||||
commands.add(new DelCommand(plugin));
|
||||
commands.add(new AddsignCommand(plugin));
|
||||
commands.add(new DelsignCommand(plugin));
|
||||
commands.add(new LinksignsCommand(plugin));
|
||||
commands.add(new StackCommand(plugin));
|
||||
commands.add(new SetlandlordCommand(plugin));
|
||||
commands.add(new MessageCommand(plugin));
|
||||
commands.add(new HelpCommand());
|
||||
commands.add(new RentCommand());
|
||||
commands.add(new UnrentCommand());
|
||||
commands.add(new BuyCommand());
|
||||
commands.add(new SellCommand());
|
||||
commands.add(new MeCommand());
|
||||
commands.add(new InfoCommand());
|
||||
commands.add(new TeleportCommand());
|
||||
commands.add(new SetteleportCommand());
|
||||
commands.add(new AddfriendCommand());
|
||||
commands.add(new DelfriendCommand());
|
||||
commands.add(new FindCommand());
|
||||
commands.add(new ResellCommand());
|
||||
commands.add(new StopresellCommand());
|
||||
commands.add(new SetrestoreCommand());
|
||||
commands.add(new SetpriceCommand());
|
||||
commands.add(new SetownerCommand());
|
||||
commands.add(new SetdurationCommand());
|
||||
commands.add(new ReloadCommand());
|
||||
commands.add(new GroupaddCommand());
|
||||
commands.add(new GroupdelCommand());
|
||||
commands.add(new GrouplistCommand());
|
||||
commands.add(new GroupinfoCommand());
|
||||
commands.add(new SchematiceventCommand());
|
||||
commands.add(new AddCommand());
|
||||
commands.add(new DelCommand());
|
||||
commands.add(new AddsignCommand());
|
||||
commands.add(new DelsignCommand());
|
||||
commands.add(new LinksignsCommand());
|
||||
commands.add(new StackCommand());
|
||||
commands.add(new SetlandlordCommand());
|
||||
commands.add(new MessageCommand());
|
||||
commands.add(new ImportCommand());
|
||||
|
||||
// Register commands in bukkit
|
||||
plugin.getCommand("AreaShop").setExecutor(this);
|
||||
plugin.getCommand("AreaShop").setExecutor(this);
|
||||
plugin.getCommand("AreaShop").setTabCompleter(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list with AreaShop commands
|
||||
* Get the list with AreaShop commands.
|
||||
* @return The list with AreaShop commands
|
||||
*/
|
||||
public ArrayList<CommandAreaShop> getCommands() {
|
||||
public List<CommandAreaShop> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows the help page for the CommandSender
|
||||
* Shows the help page for the CommandSender.
|
||||
* @param target The CommandSender to show the help to
|
||||
*/
|
||||
public void showHelp(CommandSender target) {
|
||||
@@ -84,7 +114,7 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
plugin.message(target, "help-alias");
|
||||
for(CommandAreaShop command : commands) {
|
||||
String help = command.getHelp(target);
|
||||
if(help != null && help.length() != 0) {
|
||||
if(help != null && !help.isEmpty()) {
|
||||
messages.add(help);
|
||||
}
|
||||
}
|
||||
@@ -93,36 +123,43 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
plugin.messageNoPrefix(target, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
|
||||
if(!plugin.isReady()) {
|
||||
plugin.message(sender, "general-notReady");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Redirect `/as info player <player>` to `/as me <player>`
|
||||
if(args.length == 3 && "info".equals(args[0]) && "player".equals(args[1])) {
|
||||
args[0] = "me";
|
||||
args[1] = args[2];
|
||||
}
|
||||
|
||||
// Execute command
|
||||
boolean executed = false;
|
||||
for(int i=0; i<commands.size() && !executed; i++) {
|
||||
boolean executed = false;
|
||||
for(int i = 0; i < commands.size() && !executed; i++) {
|
||||
if(commands.get(i).canExecute(command, args)) {
|
||||
commands.get(i).execute(sender, args);
|
||||
executed = true;
|
||||
}
|
||||
}
|
||||
if(!executed && args.length == 0) {
|
||||
this.showHelp(sender);
|
||||
} else if(!executed && args.length > 0) {
|
||||
// Indicate that the '/as updaterents' and '/as updatebuys' commands are removed
|
||||
if("updaterents".equalsIgnoreCase(args[0]) || "updatebuys".equalsIgnoreCase(args[0])) {
|
||||
plugin.message(sender, "reload-updateCommandChanged");
|
||||
|
||||
// Show help
|
||||
if (!executed) {
|
||||
if (args.length == 0) {
|
||||
this.showHelp(sender);
|
||||
} else {
|
||||
plugin.message(sender, "cmd-notValid");
|
||||
// Indicate that the '/as updaterents' and '/as updatebuys' commands are removed
|
||||
if("updaterents".equalsIgnoreCase(args[0]) || "updatebuys".equalsIgnoreCase(args[0])) {
|
||||
plugin.message(sender, "reload-updateCommandChanged");
|
||||
} else {
|
||||
plugin.message(sender, "cmd-notValid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,19 +170,17 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
return result;
|
||||
}
|
||||
int toCompleteNumber = args.length;
|
||||
String toCompletePrefix = args[args.length-1].toLowerCase();
|
||||
String toCompletePrefix = args[args.length - 1].toLowerCase();
|
||||
//AreaShop.debug("toCompleteNumber=" + toCompleteNumber + ", toCompletePrefix=" + toCompletePrefix + ", length=" + toCompletePrefix.length());
|
||||
if(toCompleteNumber == 1) {
|
||||
for(CommandAreaShop c : commands) {
|
||||
String begin = c.getCommandStart();
|
||||
result.add(begin.substring(begin.indexOf(' ') +1));
|
||||
result.add(begin.substring(begin.indexOf(' ') + 1));
|
||||
}
|
||||
} else {
|
||||
String[] start = new String[args.length];
|
||||
start[0] = command.getName();
|
||||
for(int i=1; i<args.length; i++) {
|
||||
start[i] = args[i-1];
|
||||
}
|
||||
System.arraycopy(args, 0, start, 1, args.length - 1);
|
||||
for(CommandAreaShop c : commands) {
|
||||
if(c.canExecute(command, args)) {
|
||||
result = c.getTabCompleteList(toCompleteNumber, start, sender);
|
||||
@@ -153,13 +188,13 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
}
|
||||
// Filter and sort the results
|
||||
if(result.size() > 0) {
|
||||
if(!result.isEmpty()) {
|
||||
SortedSet<String> set = new TreeSet<>();
|
||||
for(String suggestion : result) {
|
||||
if(suggestion.toLowerCase().startsWith(toCompletePrefix)) {
|
||||
set.add(suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.clear();
|
||||
result.addAll(set);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.CommandsFeature;
|
||||
import me.wiefferink.areashop.features.DebugFeature;
|
||||
import me.wiefferink.areashop.features.FriendsFeature;
|
||||
import me.wiefferink.areashop.features.RegionFeature;
|
||||
import me.wiefferink.areashop.features.TeleportFeature;
|
||||
import me.wiefferink.areashop.features.WorldGuardRegionFlagsFeature;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class FeatureManager extends Manager {
|
||||
|
||||
// List of defined features
|
||||
private static final Set<Class<? extends RegionFeature>> featureClasses = new HashSet<>(Arrays.asList(
|
||||
DebugFeature.class,
|
||||
SignsFeature.class,
|
||||
FriendsFeature.class,
|
||||
WorldGuardRegionFlagsFeature.class,
|
||||
TeleportFeature.class,
|
||||
CommandsFeature.class
|
||||
));
|
||||
// One instance of each feature, registered for event handling
|
||||
private final Set<RegionFeature> globalFeatures;
|
||||
private final Map<Class<? extends RegionFeature>, Constructor<? extends RegionFeature>> regionFeatureConstructors;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public FeatureManager() {
|
||||
// Instantiate and register global features (one per type, for event handling)
|
||||
globalFeatures = new HashSet<>();
|
||||
for(Class<? extends RegionFeature> clazz : featureClasses) {
|
||||
try {
|
||||
Constructor<? extends RegionFeature> constructor = clazz.getConstructor();
|
||||
RegionFeature feature = constructor.newInstance();
|
||||
feature.listen();
|
||||
globalFeatures.add(feature);
|
||||
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
|
||||
AreaShop.error("Failed to instantiate global feature:", clazz, e);
|
||||
} catch(NoSuchMethodException e) {
|
||||
// Feature does not have a global part
|
||||
}
|
||||
}
|
||||
|
||||
// Setup constructors for region specific features
|
||||
regionFeatureConstructors = new HashMap<>();
|
||||
for(Class<? extends RegionFeature> clazz : featureClasses) {
|
||||
try {
|
||||
regionFeatureConstructors.put(clazz, clazz.getConstructor(GeneralRegion.class));
|
||||
} catch(NoSuchMethodException | IllegalArgumentException e) {
|
||||
// The feature does not have a region specific part
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for(RegionFeature feature : globalFeatures) {
|
||||
feature.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciate a feature for a certain region.
|
||||
* @param region The region to create a feature for
|
||||
* @param featureClazz The class of the feature to create
|
||||
* @return The feature class
|
||||
*/
|
||||
public RegionFeature getRegionFeature(GeneralRegion region, Class<? extends RegionFeature> featureClazz) {
|
||||
try {
|
||||
return regionFeatureConstructors.get(featureClazz).newInstance(region);
|
||||
} catch(InstantiationException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
|
||||
AreaShop.error("Failed to instantiate feature", featureClazz, "for region", region, e, e.getCause());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,16 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
|
||||
public abstract class Manager {
|
||||
|
||||
final AreaShop plugin = AreaShop.getInstance();
|
||||
|
||||
/**
|
||||
* Called at shutdown of the plugin.
|
||||
*/
|
||||
public void shutdown() {
|
||||
// To override by extending classes
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.features.SignsFeature;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Sign;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -16,25 +21,34 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.material.Sign;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SignLinkerManager implements Listener {
|
||||
private AreaShop plugin = null;
|
||||
private Map<UUID, SignLinker> signLinkers;
|
||||
public class SignLinkerManager extends Manager implements Listener {
|
||||
private final Map<UUID, SignLinker> signLinkers;
|
||||
private boolean eventsRegistered;
|
||||
|
||||
public SignLinkerManager(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
public SignLinkerManager() {
|
||||
signLinkers = new HashMap<>();
|
||||
eventsRegistered = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for(UUID uuid : signLinkers.keySet()) {
|
||||
exitSignLinkMode(Bukkit.getPlayer(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let a player enter sign linking mode
|
||||
* @param player The player that has to enter sign linking mode
|
||||
* Let a player enter sign linking mode.
|
||||
* @param player The player that has to enter sign linking mode
|
||||
* @param profile The profile to use for the signs (null for default)
|
||||
*/
|
||||
public void enterSignLinkMode(Player player, String profile) {
|
||||
@@ -46,9 +60,9 @@ public class SignLinkerManager implements Listener {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Let a player exit sign linking mode
|
||||
* Let a player exit sign linking mode.
|
||||
* @param player The player that has to exit sign linking mode
|
||||
*/
|
||||
public void exitSignLinkMode(Player player) {
|
||||
@@ -59,9 +73,9 @@ public class SignLinkerManager implements Listener {
|
||||
}
|
||||
plugin.message(player, "linksigns-stopped");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the player is in sign linking mode
|
||||
* Check if the player is in sign linking mode.
|
||||
* @param player The player to check
|
||||
* @return true if the player is in sign linking mode, otherwise false
|
||||
*/
|
||||
@@ -70,7 +84,7 @@ public class SignLinkerManager implements Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* On player interactions
|
||||
* On player interactions.
|
||||
* @param event The PlayerInteractEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@@ -84,7 +98,7 @@ public class SignLinkerManager implements Listener {
|
||||
BlockIterator blockIterator = new BlockIterator(player, 100);
|
||||
while(blockIterator.hasNext()) {
|
||||
Block next = blockIterator.next();
|
||||
List<GeneralRegion> regions = Utils.getASRegionsByLocation(next.getLocation());
|
||||
List<GeneralRegion> regions = Utils.getRegions(next.getLocation());
|
||||
if(regions.size() == 1) {
|
||||
linker.setRegion(regions.get(0));
|
||||
return;
|
||||
@@ -96,7 +110,7 @@ public class SignLinkerManager implements Listener {
|
||||
plugin.message(player, "linksigns-multipleRegions", Utils.createCommaSeparatedList(names));
|
||||
plugin.message(player, "linksigns-multipleRegionsAdvice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// No regions found within the maximum range
|
||||
plugin.message(player, "linksigns-noRegions");
|
||||
@@ -109,52 +123,60 @@ public class SignLinkerManager implements Listener {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if(block == null || !(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST)) {
|
||||
if(block == null || !Materials.isSign(block.getType())) {
|
||||
plugin.message(player, "linksigns-noSign");
|
||||
return;
|
||||
}
|
||||
|
||||
SignsFeature.RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if(regionSign != null) {
|
||||
plugin.message(player, "linksigns-alreadyRegistered", regionSign.getRegion());
|
||||
return;
|
||||
}
|
||||
Sign sign = (Sign)block.getState().getData();
|
||||
linker.setSign(block.getLocation(), block.getType(), sign.getFacing());
|
||||
final BlockData blockData = block.getBlockData();
|
||||
final BlockFace rotation;
|
||||
if (blockData instanceof Sign) {
|
||||
rotation = ((Sign) blockData).getRotation();
|
||||
} else if (blockData instanceof WallSign) {
|
||||
rotation = ((WallSign) blockData).getFacing();
|
||||
} else {
|
||||
rotation = null;
|
||||
}
|
||||
linker.setSign(block.getLocation(), block.getType(), rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle disconnection players
|
||||
* Handle disconnection players.
|
||||
* @param event The PlayerQuitEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||
signLinkers.remove(event.getPlayer().getUniqueId());
|
||||
exitSignLinkMode(event.getPlayer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class to keep track of the signlinking data
|
||||
* Class to keep track of the signlinking data.
|
||||
*/
|
||||
private class SignLinker {
|
||||
private boolean hasSign = false;
|
||||
private boolean hasRegion = false;
|
||||
|
||||
public Player linker = null;
|
||||
public String profile = null;
|
||||
|
||||
|
||||
public final Player linker;
|
||||
public final String profile;
|
||||
|
||||
public GeneralRegion region = null;
|
||||
|
||||
|
||||
public Location location = null;
|
||||
public Material type = null;
|
||||
public BlockFace facing = null;
|
||||
|
||||
|
||||
public SignLinker(Player linker, String profile) {
|
||||
this.linker = linker;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
|
||||
public void setRegion(GeneralRegion region) {
|
||||
this.region = region;
|
||||
hasRegion = true;
|
||||
@@ -163,7 +185,7 @@ public class SignLinkerManager implements Listener {
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
public void setSign(Location location, Material type, BlockFace facing) {
|
||||
this.location = location;
|
||||
this.type = type;
|
||||
@@ -185,21 +207,21 @@ public class SignLinkerManager implements Listener {
|
||||
}
|
||||
region.update();
|
||||
reset();
|
||||
|
||||
|
||||
plugin.message(linker, "linksigns-next");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void reset() {
|
||||
hasSign = false;
|
||||
hasRegion = false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isComplete() {
|
||||
return hasSign && hasRegion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,875 +0,0 @@
|
||||
package me.wiefferink.areashop.messages;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* FancyMessageFormat converter, a library that enables to convert
|
||||
* messages in the FancyMessageFormat to Minecraft's bulky tellraw
|
||||
* format.
|
||||
* @author NLThijs48 | http://wiefferink.me
|
||||
* @author Tobias aka Phoenix | http://www.phoenix-iv.de
|
||||
*/
|
||||
public class FancyMessageFormat {
|
||||
|
||||
private static final char TAG_BEFORE = '[';
|
||||
private static final char TAG_AFTER = ']';
|
||||
private static final char END_TAG_INDICATOR = '/';
|
||||
|
||||
/**
|
||||
* The special character that prefixes all basic chat formatting codes.
|
||||
*/
|
||||
private static final char SIMPLE_FORMAT_PREFIX_CHAR = '\u00A7';
|
||||
|
||||
/**
|
||||
* Resets all previous chat colors or formats.
|
||||
*/
|
||||
private static final char SIMPLE_FORMAT_RESET_CHAR = 'r';
|
||||
|
||||
/**
|
||||
* Lookup table for all continuous tags (marked by [])
|
||||
*/
|
||||
private static final HashMap<String, Tag> BRACKET_TAG_LIST = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Lookup table for all interactive tags
|
||||
*/
|
||||
private static final HashMap<String, Tag> INTERACTIVE_TAG_LIST = new HashMap<>();
|
||||
|
||||
static {
|
||||
// Enlist all possible tags
|
||||
// (They go into a HashMap for lookup purposes)
|
||||
cacheTags(BRACKET_TAG_LIST, Color.class);
|
||||
cacheTags(BRACKET_TAG_LIST, FormatType.class);
|
||||
cacheTags(BRACKET_TAG_LIST, FormatCloseTag.class);
|
||||
cacheTags(BRACKET_TAG_LIST, ControlTag.class);
|
||||
// Interactive tags
|
||||
cacheTags(INTERACTIVE_TAG_LIST, ClickType.class);
|
||||
cacheTags(INTERACTIVE_TAG_LIST, HoverType.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Puts all constants in the given Tag class into the given lookup table.
|
||||
*/
|
||||
private static <T extends Tag> void cacheTags(HashMap<String, Tag> tagList, Class<T> tags) {
|
||||
for(Tag tag : tags.getEnumConstants()) {
|
||||
for(String key : tag.getTags()) {
|
||||
tagList.put(key, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// ------------------------------- Public / Interface -------------------------------
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given FancyMessageFormat message to a JSON array that can be
|
||||
* used with the tellraw command and the like.
|
||||
* @param message The mesage to convert to JSON
|
||||
* @return JSON string that can be send to a player
|
||||
*/
|
||||
public static String convertToJSON(final String message) {
|
||||
return convertToJSON(Collections.singleton(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given FancyMessageFormat message to a JSON array that can be
|
||||
* used with the tellraw command and the like.
|
||||
* @param inputLines Input message split at line breaks.
|
||||
* @return JSON string that can be send to a player
|
||||
*/
|
||||
public static String convertToJSON(final Iterable<String> inputLines) {
|
||||
ArrayList<String> lines = cleanInputString(inputLines);
|
||||
|
||||
LinkedList<InteractiveMessagePart> message = parse(lines);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
if(message.size() == 1) {
|
||||
sb.append(message.getFirst().toJSON());
|
||||
} else if(message.size() > 0) {
|
||||
sb.append("{\"text\":\"\",\"extra\":[");
|
||||
for(InteractiveMessagePart messagePart : message) {
|
||||
sb.append(messagePart.toJSON());
|
||||
sb.append(',');
|
||||
}
|
||||
sb.deleteCharAt(sb.length()-1);
|
||||
sb.append("]}");
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given FancyMessageFormat message to a String containing control characters
|
||||
* for formatting that can be used for console outputs, but also for normal player
|
||||
* messages.
|
||||
* <p>
|
||||
* The returned message will only contain colors, bold, italic, underlining and 'magic'
|
||||
* characters. Hovers and other advanced tellraw tags will be skipped.
|
||||
* @param message Input message split at line breaks.
|
||||
* @return Plain message that can be send
|
||||
*/
|
||||
public static String convertToConsole(final String message) {
|
||||
return convertToConsole(Collections.singleton(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given FancyMessageFormat message to a String containing control characters
|
||||
* for formatting that can be used for console outputs, but also for normal player
|
||||
* messages.
|
||||
* <p>
|
||||
* The returned message will only contain colors, bold, italic, underlining and 'magic'
|
||||
* characters. Hovers and other advanced tellraw tags will be skipped.
|
||||
* @param inputLines The raw message lines to process
|
||||
* @return Plain message that can be send
|
||||
*/
|
||||
public static String convertToConsole(final Iterable<String> inputLines) {
|
||||
if(inputLines == null) {
|
||||
return null;
|
||||
}
|
||||
LinkedList<InteractiveMessagePart> parts = parse(inputLines, false);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(InteractiveMessagePart part : parts) {
|
||||
result.append(part.toSimpleString());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a message at the specified position
|
||||
* @param message The current message
|
||||
* @param insert The message to insert
|
||||
* @param line The line number to insert at
|
||||
* @param start The start of the variable to replace
|
||||
* @param end The end of the variable to replace
|
||||
*/
|
||||
public static void insertMessage(List<String> message, List<String> insert, int line, int start, int end) {
|
||||
if(insert == null || line < 0 || line >= message.size() || start < 0 || end < 0) {
|
||||
return;
|
||||
}
|
||||
String lineContent = message.remove(line);
|
||||
if(start > lineContent.length() || end > lineContent.length()) {
|
||||
return;
|
||||
}
|
||||
if(isTaggedInteractive(lineContent)) {
|
||||
lineContent = lineContent.replace("", "");
|
||||
message.add(line, lineContent.substring(0, start)+convertToConsole(insert)+lineContent.substring(end));
|
||||
return;
|
||||
}
|
||||
// Find interactive lines meant for this message
|
||||
List<String> interactives = new ArrayList<>();
|
||||
while(line < message.size() && isTaggedInteractive(message.get(line))) {
|
||||
interactives.add(message.remove(line));
|
||||
}
|
||||
// Split the line and add the parts
|
||||
int at = line;
|
||||
if(start > 0) {
|
||||
message.add(line, lineContent.substring(0, start));
|
||||
at++;
|
||||
message.addAll(at, interactives);
|
||||
at += interactives.size();
|
||||
}
|
||||
message.addAll(at, insert);
|
||||
at += insert.size();
|
||||
message.addAll(at, interactives);
|
||||
at += interactives.size();
|
||||
if(end < lineContent.length()) {
|
||||
message.add(at, lineContent.substring(end));
|
||||
at++;
|
||||
message.addAll(at, interactives);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// ------------------------------- Private functions -------------------------------
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* <ul>
|
||||
* <li>Splits lines at line breaks (creating a new line in the Array).
|
||||
* <li>Removes empty lines at the beginning.
|
||||
* <li>Removes lines with properties in front of the first text-line.
|
||||
* </ul>
|
||||
*/
|
||||
private static ArrayList<String> cleanInputString(Iterable<String> inputLines) {
|
||||
// Split lines at line breaks
|
||||
// In the end we will have a list with one line per element
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
for(String line : inputLines) {
|
||||
lines.addAll(Arrays.asList(line.split("\\r?\\n")));
|
||||
}
|
||||
|
||||
// Remove any special lines at the start (a real text line should be first)
|
||||
while(!lines.isEmpty() && isTaggedInteractive(lines.get(0))) {
|
||||
lines.remove(0);
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
private static LinkedList<InteractiveMessagePart> parse(Iterable<String> inputLines) {
|
||||
return parse(inputLines, true);
|
||||
}
|
||||
|
||||
private static LinkedList<InteractiveMessagePart> parse(final Iterable<String> inputLines, boolean doInteractives) {
|
||||
LinkedList<InteractiveMessagePart> message = new LinkedList<>();
|
||||
|
||||
Color currentColor = null;
|
||||
Set<FormatType> currentFormatting = new HashSet<>();
|
||||
|
||||
lineLoop:
|
||||
for(String line : inputLines) {
|
||||
InteractiveMessagePart messagePart;
|
||||
TaggedContent interactiveTag = getInteractiveTag(line);
|
||||
boolean isTextLine = interactiveTag == null;
|
||||
if(!doInteractives && !isTextLine) {
|
||||
continue;
|
||||
}
|
||||
boolean isHoverLine = false;
|
||||
|
||||
if(isTextLine) {
|
||||
messagePart = new InteractiveMessagePart();
|
||||
message.add(messagePart);
|
||||
} else /* if Interactive formatting */ {
|
||||
if(message.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
messagePart = message.getLast();
|
||||
Tag tag = interactiveTag.tag;
|
||||
if(tag instanceof ClickType) {
|
||||
messagePart.clickType = (ClickType)interactiveTag.tag;
|
||||
messagePart.clickContent = interactiveTag.subsequentContent;
|
||||
} else if(tag instanceof HoverType) {
|
||||
line = interactiveTag.subsequentContent;
|
||||
isHoverLine = true;
|
||||
if(messagePart.hoverType != tag) {
|
||||
// Hover type changed
|
||||
messagePart.hoverContent = new LinkedList<>();
|
||||
messagePart.hoverType = (HoverType)tag;
|
||||
}
|
||||
// Add hover content below
|
||||
}
|
||||
}
|
||||
|
||||
if(isTextLine || isHoverLine) {
|
||||
// Parse inline tags
|
||||
|
||||
Color currentLineColor = currentColor;
|
||||
Set<FormatType> currentLineFormatting = currentFormatting;
|
||||
LinkedList<TextMessagePart> targetList = messagePart.content;
|
||||
boolean parseBreak = true;
|
||||
if(isHoverLine) {
|
||||
// Reset - use own
|
||||
currentLineColor = null;
|
||||
currentLineFormatting = new HashSet<>();
|
||||
targetList = messagePart.hoverContent;
|
||||
parseBreak = false;
|
||||
|
||||
// Add line break after previous hover line
|
||||
if(!targetList.isEmpty()) {
|
||||
targetList.getLast().text += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// Split into pieces at places where formatting changes
|
||||
while(!line.isEmpty()) {
|
||||
String textToAdd;
|
||||
TaggedContent nextTag = getNextTag(line, parseBreak);
|
||||
boolean tagged = nextTag != null;
|
||||
|
||||
if(!tagged) {
|
||||
textToAdd = line;
|
||||
line = "";
|
||||
} else {
|
||||
textToAdd = nextTag.precedingContent;
|
||||
line = nextTag.subsequentContent;
|
||||
}
|
||||
|
||||
// Add a text part with the correct formatting
|
||||
if((tagged && nextTag.tag == ControlTag.BREAK) || !textToAdd.isEmpty()) {
|
||||
TextMessagePart part = new TextMessagePart();
|
||||
part.text = textToAdd;
|
||||
part.formatTypes = new HashSet<>(currentLineFormatting);
|
||||
part.color = currentLineColor;
|
||||
targetList.add(part);
|
||||
}
|
||||
|
||||
// Handle the change in formatting if a Tag has been detected (this needs to be after creating the InteractiveMessagePart)
|
||||
if(tagged) {
|
||||
// Handle the formatting tag
|
||||
Tag tag = nextTag.tag;
|
||||
if(tag instanceof Color) {
|
||||
currentLineColor = (Color)tag;
|
||||
} else if(tag instanceof FormatType) {
|
||||
currentLineFormatting.add((FormatType)tag);
|
||||
} else if(tag instanceof FormatCloseTag) {
|
||||
currentLineFormatting.remove(((FormatCloseTag)tag).closes);
|
||||
} else if(tag == ControlTag.BREAK) {
|
||||
if(!targetList.isEmpty()) {
|
||||
targetList.getLast().text += '\n';
|
||||
}
|
||||
continue lineLoop;
|
||||
} else if(tag == ControlTag.RESET) {
|
||||
currentLineFormatting.clear();
|
||||
currentLineColor = Color.WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!isHoverLine) {
|
||||
// Adapt global attributes
|
||||
currentColor = currentLineColor;
|
||||
if(messagePart.content.size() == 0) { // Prevent interactive parts without content
|
||||
message.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches and returns the first continuous tag found in the given String.
|
||||
* @return The tag (plus its preceding and subsequent content) if found.
|
||||
* Null if nothing is found.
|
||||
*/
|
||||
private static TaggedContent getNextTag(String line, boolean parseBreak) {
|
||||
Pattern pattern = Pattern.compile("\\[[/a-zA-Z1-9]+\\]|&[1-9abcdeflonskr]");
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
// TODO Fix for escape things, and something with parseBreak?
|
||||
while(matcher.find()) {
|
||||
Tag tag = null;
|
||||
if(matcher.group().startsWith("&")) {
|
||||
for(Color color : Color.class.getEnumConstants()) {
|
||||
if(color.getNativeFormattingCode() == matcher.group().charAt(1)) {
|
||||
tag = color;
|
||||
}
|
||||
}
|
||||
for(FormatType format : FormatType.class.getEnumConstants()) {
|
||||
if(format.getNativeFormattingCode() == matcher.group().charAt(1)) {
|
||||
tag = format;
|
||||
}
|
||||
}
|
||||
if(matcher.group().charAt(1) == SIMPLE_FORMAT_RESET_CHAR) {
|
||||
tag = ControlTag.RESET;
|
||||
}
|
||||
} else {
|
||||
tag = BRACKET_TAG_LIST.get(matcher.group().substring(1, matcher.group().length()-1).toLowerCase());
|
||||
}
|
||||
// Continue search if we found something like [abc] that is not a tag
|
||||
if(tag != null) {
|
||||
return new TaggedContent(line.substring(0, matcher.start()), tag, line.substring(matcher.end()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
/*
|
||||
for(int startIndex = 0; startIndex < line.length(); startIndex++) {
|
||||
int start = line.indexOf(TAG_BEFORE, startIndex);
|
||||
if(start != -1) {
|
||||
int end = line.indexOf(TAG_AFTER, start);
|
||||
if(end != -1) {
|
||||
String inBetween = line.substring(start+1, end).toLowerCase();
|
||||
if(BRACKET_TAG_LIST.containsKey(inBetween)) {
|
||||
Tag tag = BRACKET_TAG_LIST.get(inBetween);
|
||||
if(tag == ControlTag.ESCAPE) {
|
||||
// Ignore next char
|
||||
line = line.substring(0, start)+line.substring(end+1);
|
||||
startIndex = start;
|
||||
} else if(!parseBreak && tag == ControlTag.ESCAPE) {
|
||||
// Ignore break
|
||||
startIndex = end+1;
|
||||
} else {
|
||||
String previousContent = line.substring(0, start);
|
||||
String subsequentContent = line.substring(end+1);
|
||||
return new TaggedContent(previousContent, tag, subsequentContent);
|
||||
}
|
||||
} else {
|
||||
startIndex = start;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the given line defines an interactive property (e.g. "hover: myText")
|
||||
* the tag / property will be returned. Otherwise null is returned.
|
||||
*/
|
||||
private static TaggedContent getInteractiveTag(String line) {
|
||||
for(int index = 0; index < line.length(); index++) {
|
||||
char c = line.charAt(index);
|
||||
if(c == ' ' || c == '\t') {
|
||||
// Ignore (Skip spacing)
|
||||
} else {
|
||||
int end = line.indexOf(": ", index);
|
||||
if(end != -1) {
|
||||
String inBetween = line.substring(index, end).toLowerCase();
|
||||
if(INTERACTIVE_TAG_LIST.containsKey(inBetween)) {
|
||||
Tag tag = INTERACTIVE_TAG_LIST.get(inBetween);
|
||||
String subsequentContent = line.substring(end+2);
|
||||
return new TaggedContent(null, tag, subsequentContent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a line is an advanced declaration like hover or command
|
||||
* @param line The line to check
|
||||
* @return true if the line is interactive, false when it is a text line
|
||||
*/
|
||||
public static boolean isTaggedInteractive(String line) {
|
||||
return getInteractiveTag(line) != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Produce a string in double quotes with backslash sequences in all the
|
||||
* right places.
|
||||
* @param string A String
|
||||
* @return A String correctly formatted for insertion in a JSON text.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002 JSON.org
|
||||
* Licensed under the Apache License, Version 2.0
|
||||
*/
|
||||
private static String quoteStringJson(String string) {
|
||||
if(string == null || string.length() == 0) {
|
||||
return "\"\"";
|
||||
}
|
||||
|
||||
char c;
|
||||
int i;
|
||||
int len = string.length();
|
||||
StringBuilder sb = new StringBuilder(len+4);
|
||||
String t;
|
||||
|
||||
sb.append('"');
|
||||
for(i = 0; i < len; i += 1) {
|
||||
c = string.charAt(i);
|
||||
switch(c) {
|
||||
case '\\':
|
||||
case '"':
|
||||
sb.append('\\');
|
||||
sb.append(c);
|
||||
break;
|
||||
case '/':
|
||||
sb.append('\\');
|
||||
sb.append(c);
|
||||
break;
|
||||
case '\b':
|
||||
sb.append("\\b");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
default:
|
||||
if(c < ' ') {
|
||||
t = "000"+Integer.toHexString(c);
|
||||
sb.append("\\u");
|
||||
sb.append(t.substring(t.length()-4));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append('"');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// ------------------------------- Helper classes -------------------------------
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
private static class TaggedContent {
|
||||
final String precedingContent;
|
||||
final Tag tag;
|
||||
final String subsequentContent;
|
||||
|
||||
public TaggedContent(String pre, Tag tag, String sub) {
|
||||
this.precedingContent = pre;
|
||||
this.tag = tag;
|
||||
this.subsequentContent = sub;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds a string with basic (non-interactive) formatting.
|
||||
*/
|
||||
private static class TextMessagePart {
|
||||
String text = "";
|
||||
Color color = null;
|
||||
Set<FormatType> formatTypes = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Get a simple colored/formatted string
|
||||
* @return String with formatting
|
||||
*/
|
||||
String toSimpleString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// Color
|
||||
if(color != null) {
|
||||
sb.append(SIMPLE_FORMAT_PREFIX_CHAR);
|
||||
sb.append(color.getNativeFormattingCode());
|
||||
}
|
||||
// Formatting
|
||||
for(FormatType format : formatTypes) {
|
||||
sb.append(SIMPLE_FORMAT_PREFIX_CHAR);
|
||||
sb.append(format.getNativeFormattingCode());
|
||||
}
|
||||
// Text
|
||||
sb.append(text);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON component for this message part
|
||||
* @return This part formatted in JSON
|
||||
*/
|
||||
String toJSON() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('{');
|
||||
sb.append("\"text\":").append(quoteStringJson(text));
|
||||
if(color != null && color != Color.WHITE) {
|
||||
sb.append(",\"color\":\"").append(color.jsonValue).append("\"");
|
||||
}
|
||||
for(FormatType formatting : formatTypes) {
|
||||
sb.append(",\"");
|
||||
sb.append(formatting.jsonKey).append("\":");
|
||||
sb.append("true");
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
boolean hasFormatting() {
|
||||
return !(color == Color.WHITE && formatTypes.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TextMessagePart(text:"+text+", color:"+color+", formatting:"+formatTypes.toString()+")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds a string with interactive formatting.
|
||||
*/
|
||||
private static class InteractiveMessagePart {
|
||||
|
||||
LinkedList<TextMessagePart> content = new LinkedList<>();
|
||||
|
||||
// Click
|
||||
ClickType clickType = null;
|
||||
String clickContent = "";
|
||||
|
||||
// Hover
|
||||
HoverType hoverType = null;
|
||||
LinkedList<TextMessagePart> hoverContent = null;
|
||||
|
||||
/**
|
||||
* Get a simple colored/formatted string
|
||||
* @return String with formatting
|
||||
*/
|
||||
String toSimpleString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(TextMessagePart part : content) {
|
||||
sb.append(part.toSimpleString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON component for this message part
|
||||
* @return This part formatted in JSON
|
||||
*/
|
||||
String toJSON() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(content.size() == 1) {
|
||||
// Add attributes to TextMessagePart object
|
||||
sb.append(content.getFirst().toJSON());
|
||||
sb.deleteCharAt(sb.length()-1);
|
||||
} else {
|
||||
sb.append('{');
|
||||
sb.append("\"text\":\"\",\"extra\":[");
|
||||
for(TextMessagePart textPart : content) {
|
||||
sb.append(textPart.toJSON());
|
||||
sb.append(',');
|
||||
}
|
||||
sb.deleteCharAt(sb.length()-1);
|
||||
sb.append(']');
|
||||
}
|
||||
if(clickType != null) {
|
||||
sb.append(',');
|
||||
sb.append("\"clickEvent\":{");
|
||||
sb.append("\"action\":\"").append(clickType.getJsonKey()).append("\",");
|
||||
sb.append("\"value\":").append(quoteStringJson(clickContent));
|
||||
sb.append('}');
|
||||
}
|
||||
if(hoverType != null) {
|
||||
sb.append(',');
|
||||
sb.append("\"hoverEvent\":{");
|
||||
sb.append("\"action\":\"").append(hoverType.getJsonKey()).append("\",");
|
||||
sb.append("\"value\":");
|
||||
if(hoverContent.size() == 1) {
|
||||
TextMessagePart hoverPart = hoverContent.getFirst();
|
||||
if(hoverPart.hasFormatting()) {
|
||||
sb.append(hoverPart.toJSON());
|
||||
} else {
|
||||
sb.append(quoteStringJson(hoverPart.text));
|
||||
}
|
||||
} else {
|
||||
sb.append('[');
|
||||
for(TextMessagePart hoverPart : hoverContent) {
|
||||
sb.append(hoverPart.toJSON());
|
||||
sb.append(',');
|
||||
}
|
||||
sb.deleteCharAt(sb.length()-1);
|
||||
sb.append(']');
|
||||
}
|
||||
sb.append('}');
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InteractiveMessagePart(textMessageParts:"+content+", clickType:"+clickType+", clickContent:"+clickContent+", hoverType:"+hoverType+", hoverContent:"+hoverContent+")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------- Tags ---------------------------------------
|
||||
|
||||
|
||||
interface Tag {
|
||||
/**
|
||||
* Tag text(s) used in the FancyMessageFormat (The text between '[' and ']')
|
||||
*/
|
||||
String[] getTags();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates formatting that is applied until explicitly stopped.
|
||||
* Can also be used in simple Minecraft messages (Non-JSON).
|
||||
*/
|
||||
interface ContinuousTag extends Tag {
|
||||
/**
|
||||
* The character that defines upcoming formatting in a native (non-JSON) Minecraft message.
|
||||
*/
|
||||
char getNativeFormattingCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates formatting that allows cursor interaction. Requires the
|
||||
* Minecraft JSON / tellraw format.
|
||||
*/
|
||||
interface InteractiveMessageTag extends Tag {
|
||||
String getJsonKey();
|
||||
}
|
||||
|
||||
|
||||
enum Color implements ContinuousTag {
|
||||
WHITE('f'),
|
||||
BLACK('0'),
|
||||
BLUE('9'),
|
||||
DARK_BLUE('1', "darkblue"),
|
||||
GREEN('a'),
|
||||
DARK_GREEN('2', "darkgreen"),
|
||||
AQUA('b'),
|
||||
DARK_AQUA('3', "darkaqua"),
|
||||
RED('c'),
|
||||
DARK_RED('4', "darkred"),
|
||||
LIGHT_PURPLE('d', "lightpurple"),
|
||||
DARK_PURPLE('5', "darkpurple"),
|
||||
YELLOW('e'),
|
||||
GOLD('6'),
|
||||
GRAY('7', "grey"),
|
||||
DARK_GRAY('8', "dark_grey", "darkgray", "darkgrey");
|
||||
|
||||
final char bytecode;
|
||||
final String jsonValue;
|
||||
final String[] tags;
|
||||
|
||||
Color(char bytecode, String... extraTags) {
|
||||
this.bytecode = bytecode;
|
||||
this.jsonValue = this.name().toLowerCase();
|
||||
this.tags = new String[extraTags.length+1];
|
||||
this.tags[0] = this.name().toLowerCase();
|
||||
System.arraycopy(extraTags, 0, this.tags, 1, extraTags.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getNativeFormattingCode() {
|
||||
return bytecode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum FormatType implements ContinuousTag {
|
||||
BOLD('l', "bold", "b", "bold"),
|
||||
ITALIC('o', "italic", "i", "italic"),
|
||||
UNDERLINE('n', "underlined", "u", "underline"),
|
||||
STRIKETHROUGH('s', "strikethrough", "s", "strike", "strikethrough"),
|
||||
OBFUSCATE('k', "obfuscated", "obfuscate");
|
||||
|
||||
final char bytecode;
|
||||
final String jsonKey;
|
||||
final String[] tags;
|
||||
|
||||
FormatType(char bytecode, String jsonKey, String... tags) {
|
||||
this.bytecode = bytecode;
|
||||
this.jsonKey = jsonKey;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getNativeFormattingCode() {
|
||||
return bytecode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum FormatCloseTag implements Tag {
|
||||
BOLD_END(FormatType.BOLD),
|
||||
ITALIC_END(FormatType.ITALIC),
|
||||
UNDERLINE_END(FormatType.UNDERLINE),
|
||||
STRIKETHROUGH_END(FormatType.STRIKETHROUGH),
|
||||
OBFUSCATE_END(FormatType.OBFUSCATE);
|
||||
|
||||
/**
|
||||
* Formatting that is stopped at this point
|
||||
*/
|
||||
final FormatType closes;
|
||||
private final String[] tags;
|
||||
|
||||
FormatCloseTag(FormatType openingTag) {
|
||||
this.closes = openingTag;
|
||||
|
||||
// Auto-generate close tags
|
||||
tags = new String[closes.tags.length];
|
||||
for(int i = 0; i < tags.length; i++) {
|
||||
tags[i] = END_TAG_INDICATOR+closes.tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum ControlTag implements Tag {
|
||||
BREAK("break"),
|
||||
ESCAPE("esc"),
|
||||
RESET("reset");
|
||||
|
||||
private final String[] tags;
|
||||
|
||||
ControlTag(String... tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Types of clicking
|
||||
*/
|
||||
enum ClickType implements InteractiveMessageTag {
|
||||
LINK("open_url", "link"),
|
||||
COMMAND("run_command", "command"),
|
||||
SUGGEST("suggest_command", "suggest");
|
||||
|
||||
private final String jsonKey;
|
||||
private final String[] tags;
|
||||
|
||||
ClickType(String jsonKey, String... tags) {
|
||||
this.jsonKey = jsonKey;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonKey() {
|
||||
return jsonKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum HoverType implements InteractiveMessageTag {
|
||||
HOVER;
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return new String[]{"hover"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonKey() {
|
||||
return "show_text";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package me.wiefferink.areashop.messages;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class LanguageManager {
|
||||
private AreaShop plugin = null;
|
||||
private String languages[] = {"EN", "NL", "FR", "DE", "NO", "RU"};
|
||||
private Map<String, List<String>> currentLanguage, defaultLanguage;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public LanguageManager(AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
startup();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the default language files and open the current and backup language file
|
||||
*/
|
||||
public void startup() {
|
||||
this.saveDefaults();
|
||||
currentLanguage = loadLanguage(plugin.getConfig().getString("language"));
|
||||
defaultLanguage = loadLanguage(languages[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the default language files if not already present
|
||||
*/
|
||||
public void saveDefaults() {
|
||||
// Create the language folder if it not exists
|
||||
File langFolder;
|
||||
langFolder = new File(plugin.getDataFolder()+File.separator+AreaShop.languageFolder);
|
||||
if(!langFolder.exists()) {
|
||||
if(!langFolder.mkdirs()) {
|
||||
AreaShop.warn("Could not create language directory: "+langFolder.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the language files, overwrites if a file already exists
|
||||
// Overriding is necessary because otherwise with an update the new lang files would not be used
|
||||
File langFile;
|
||||
for(String language : languages) {
|
||||
langFile = new File(plugin.getDataFolder()+File.separator+AreaShop.languageFolder+File.separator+language+".yml");
|
||||
try(
|
||||
InputStream input = plugin.getResource(AreaShop.languageFolder+"/"+language+".yml");
|
||||
OutputStream output = new FileOutputStream(langFile)
|
||||
) {
|
||||
if(input == null) {
|
||||
AreaShop.warn("Could not save default language to the '"+AreaShop.languageFolder+"' folder: "+language+".yml");
|
||||
continue;
|
||||
}
|
||||
int read;
|
||||
byte[] bytes = new byte[1024];
|
||||
while((read = input.read(bytes)) != -1) {
|
||||
output.write(bytes, 0, read);
|
||||
}
|
||||
input.close();
|
||||
output.close();
|
||||
} catch(IOException e) {
|
||||
AreaShop.warn("Something went wrong saving a default language file: "+langFile.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified language
|
||||
* @param key The language to load
|
||||
* @return Map with the messages loaded from the file
|
||||
*/
|
||||
public Map<String, List<String>> loadLanguage(String key) {
|
||||
return loadLanguage(key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified language
|
||||
* @param key The language to load
|
||||
* @param convert try conversion or not
|
||||
* @return Map with the messages loaded from the file
|
||||
*/
|
||||
private Map<String, List<String>> loadLanguage(String key, boolean convert) {
|
||||
Map<String, List<String>> result = new HashMap<>();
|
||||
|
||||
// Load the strings
|
||||
boolean isTransifexFile = false;
|
||||
File file = new File(plugin.getDataFolder()+File.separator+AreaShop.languageFolder+File.separator+key+".yml");
|
||||
try(
|
||||
InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)
|
||||
) {
|
||||
YamlConfiguration ymlFile = YamlConfiguration.loadConfiguration(reader);
|
||||
// Detect empty language files, happens when the YAML parser prints an exception (it does return an empty YamlConfiguration though)
|
||||
if(ymlFile.getKeys(false).isEmpty()) {
|
||||
AreaShop.warn("Language file "+key+".yml has zero messages.");
|
||||
return result;
|
||||
}
|
||||
// Detect language files downloaded from Transifex and convert them
|
||||
if(ymlFile.getKeys(false).size() == 1) {
|
||||
for(String languageKey : ymlFile.getKeys(false)) {
|
||||
if(ymlFile.isConfigurationSection(languageKey)) {
|
||||
isTransifexFile = convert;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Retrieve the messages from the YAML file and create the result
|
||||
if(!isTransifexFile) {
|
||||
for(String messageKey : ymlFile.getKeys(false)) {
|
||||
if(ymlFile.isList(messageKey)) {
|
||||
result.put(messageKey, new ArrayList<>(ymlFile.getStringList(messageKey)));
|
||||
} else {
|
||||
result.put(messageKey, new ArrayList<>(Collections.singletonList(ymlFile.getString(messageKey))));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
AreaShop.warn("Could not load set language file: "+file.getAbsolutePath());
|
||||
}
|
||||
|
||||
if(isTransifexFile) {
|
||||
if(!Transifex.convertFrom(file)) {
|
||||
AreaShop.warn("Failed to convert "+file.getName()+" from the Transifex layout to the AreaShop layout, check the errors above");
|
||||
}
|
||||
return loadLanguage(key, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the message for a certain key, without doing any processing
|
||||
* @param key The key of the message to get
|
||||
* @return The message as a list of strings
|
||||
*/
|
||||
public List<String> getRawMessage(String key) {
|
||||
List<String> message;
|
||||
if(key.equalsIgnoreCase(Message.CHATLANGUAGEVARIABLE)) {
|
||||
message = plugin.getChatPrefix();
|
||||
} else if(currentLanguage.containsKey(key)) {
|
||||
message = currentLanguage.get(key);
|
||||
} else {
|
||||
message = defaultLanguage.get(key);
|
||||
}
|
||||
if(message == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return new ArrayList<>(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
package me.wiefferink.areashop.messages;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Message {
|
||||
|
||||
public static final String VARIABLESTART = "%";
|
||||
public static final String VARIABLEEND = "%";
|
||||
public static final String LANGUAGEVARIABLE = "lang:";
|
||||
public static final String CHATLANGUAGEVARIABLE = "prefix";
|
||||
public static final int REPLACEMENTLIMIT = 50; // Maximum number of replacement rounds (the replaced value can have variables again)
|
||||
public static final int MAXIMUMJSONLENGTH = 30000; // Limit of the client is 32767 for the complete message
|
||||
private static boolean fancyWorks = true;
|
||||
|
||||
private List<String> message;
|
||||
private Object[] replacements;
|
||||
private String key = null;
|
||||
|
||||
/**
|
||||
* Internal use only
|
||||
*/
|
||||
private Message() {
|
||||
message = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty message object
|
||||
* @return this
|
||||
*/
|
||||
public static Message none() {
|
||||
return new Message();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a message from a language key
|
||||
* @param key The key of the message to use
|
||||
* @return this
|
||||
*/
|
||||
public static Message fromKey(String key) {
|
||||
return new Message().setMessageFromKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a message from a string
|
||||
* @param message The message to use
|
||||
* @return this
|
||||
*/
|
||||
public static Message fromString(String message) {
|
||||
return new Message().setMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a message from a string list
|
||||
* @param message The message to use
|
||||
* @return this
|
||||
*/
|
||||
public static Message fromList(List<String> message) {
|
||||
return new Message().setMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message with all replacements done
|
||||
* @return Message as a list
|
||||
*/
|
||||
public List<String> get() {
|
||||
executeReplacements();
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message with all replacements done
|
||||
* @param limit the limit to hold to
|
||||
* @return Message as a list
|
||||
*/
|
||||
private List<String> get(Limit limit) {
|
||||
if(limit.reached()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
executeReplacements(limit);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw message without replacing anything
|
||||
* @return The message
|
||||
*/
|
||||
public List<String> getRaw() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plain string for the message (for example for using in the console)
|
||||
* @return The message as simple string
|
||||
*/
|
||||
public String getPlain() {
|
||||
executeReplacements();
|
||||
return FancyMessageFormat.convertToConsole(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the default prefix to the message
|
||||
* @param doIt true if the prefix should be added, otherwise false
|
||||
* @return this
|
||||
*/
|
||||
public Message prefix(boolean doIt) {
|
||||
if(doIt) {
|
||||
message.add(0, VARIABLESTART+LANGUAGEVARIABLE+CHATLANGUAGEVARIABLE+VARIABLEEND);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message prefix() {
|
||||
return prefix(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the replacements to apply to the message
|
||||
* @param replacements The replacements to apply
|
||||
* - GeneralRegion: All region replacements are applied
|
||||
* - Message: Message is inserted
|
||||
* - other: index tag is replaced, like %0%
|
||||
* @return this
|
||||
*/
|
||||
public Message replacements(Object... replacements) {
|
||||
this.replacements = replacements;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append lines to the message
|
||||
* @param lines The lines to append
|
||||
* @return this
|
||||
*/
|
||||
public Message append(List<String> lines) {
|
||||
message.addAll(lines);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a message to this message
|
||||
* @param message The message to append
|
||||
* @return this
|
||||
*/
|
||||
public Message append(Message message) {
|
||||
return append(message.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Append lines to the message
|
||||
* @param line The line to append
|
||||
* @return this
|
||||
*/
|
||||
public Message append(String line) {
|
||||
message.add(line);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the message to a target
|
||||
* @param target The target to send the message to (Player, CommandSender, Logger)
|
||||
* @return this
|
||||
*/
|
||||
public Message send(Object target) {
|
||||
if(message == null || message.size() == 0 || (message.size() == 1 && message.get(0).length() == 0) || target == null) {
|
||||
return this;
|
||||
}
|
||||
executeReplacements();
|
||||
if(target instanceof Player) {
|
||||
boolean sendPlain = true;
|
||||
if(AreaShop.getInstance().getConfig().getBoolean("useFancyMessages") && fancyWorks) {
|
||||
try {
|
||||
String jsonString = FancyMessageFormat.convertToJSON(message);
|
||||
if(jsonString.length() > MAXIMUMJSONLENGTH) {
|
||||
AreaShop.getInstance().getLogger().severe("Message with key "+key+" could not be send, results in a JSON string that is too big to send to the client, start of the message: "+Utils.getMessageStart(this, 100));
|
||||
return this;
|
||||
}
|
||||
boolean result = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw "+((Player)target).getName()+" "+jsonString);
|
||||
sendPlain = !result;
|
||||
fancyWorks = result;
|
||||
} catch(Exception e) {
|
||||
fancyWorks = false;
|
||||
AreaShop.getInstance().getLogger().warning("Sending fancy message did not work, falling back to plain messages. Message key: "+key);
|
||||
AreaShop.debug(ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
if(sendPlain) { // Fancy messages disabled or broken
|
||||
((Player)target).sendMessage(FancyMessageFormat.convertToConsole(message));
|
||||
}
|
||||
} else {
|
||||
String plainMessage = FancyMessageFormat.convertToConsole(message);
|
||||
if(!AreaShop.getInstance().getConfig().getBoolean("useColorsInConsole")) {
|
||||
plainMessage = ChatColor.stripColor(plainMessage);
|
||||
}
|
||||
if(target instanceof CommandSender) {
|
||||
((CommandSender)target).sendMessage(plainMessage);
|
||||
} else if(target instanceof Logger) {
|
||||
((Logger)target).info(plainMessage);
|
||||
} else {
|
||||
AreaShop.getInstance().getLogger().warning("Could not send message, target is wrong: "+plainMessage);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// INTERNAL METHODS
|
||||
|
||||
/**
|
||||
* Set the internal message
|
||||
* @param message The message to set
|
||||
* @return this
|
||||
*/
|
||||
private Message setMessage(List<String> message) {
|
||||
this.message = message;
|
||||
if(this.message == null) {
|
||||
this.message = new ArrayList<>();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the internal message with a key
|
||||
* @param key The message key to get the message for
|
||||
* @return this
|
||||
*/
|
||||
private Message setMessageFromKey(String key) {
|
||||
this.key = key;
|
||||
return this.setMessage(AreaShop.getInstance().getLanguageManager().getRawMessage(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the internal message with a string
|
||||
* @param message The message to set
|
||||
* @return this
|
||||
*/
|
||||
private Message setMessage(String message) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(message);
|
||||
return this.setMessage(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply all replacements to the message
|
||||
*/
|
||||
private void executeReplacements() {
|
||||
executeReplacements(new Limit(REPLACEMENTLIMIT, this));
|
||||
}
|
||||
|
||||
private void executeReplacements(Limit limit) {
|
||||
// Replace variables until they are all gone, or when the limit is reached
|
||||
Pattern variable = Pattern.compile(Pattern.quote(VARIABLESTART)+"[a-zA-Z]+"+Pattern.quote(VARIABLEEND));
|
||||
|
||||
try {
|
||||
boolean shouldReplace = true;
|
||||
while(shouldReplace) {
|
||||
List<String> original = new ArrayList<>(message);
|
||||
|
||||
limit.left--;
|
||||
if(limit.reached()) {
|
||||
if(!limit.notified) {
|
||||
limit.notified = true;
|
||||
AreaShop.getInstance().getLogger().severe("Reached replacement limit, probably has replacements loops, problematic message key: "+limit.message.key+", first characters of the message: "+Utils.getMessageStart(limit.message, 100));
|
||||
}
|
||||
break;
|
||||
}
|
||||
replaceArgumentVariables(limit);
|
||||
replaceLanguageVariables(limit);
|
||||
|
||||
shouldReplace = !message.equals(original);
|
||||
}
|
||||
} catch(StackOverflowError e) {
|
||||
limit.left = 0;
|
||||
limit.notified = true;
|
||||
AreaShop.getInstance().getLogger().severe("Too many recursive replacements for message with key: "+limit.message.key+" (probably includes itself as replacement), start of the message: "+Utils.getMessageStart(limit.message, 100));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace argument variables in a message
|
||||
* The arguments to apply as replacements:
|
||||
* - If it is a GeneralRegion the replacements of the region will be applied
|
||||
* - Else the parameter will replace its number surrounded with VARIABLESTART and VARIABLEEND
|
||||
*/
|
||||
private void replaceArgumentVariables(Limit limit) {
|
||||
if(message == null || message.size() == 0 || replacements == null || limit.reached()) {
|
||||
return;
|
||||
}
|
||||
boolean result = false;
|
||||
for(int i = 0; i < message.size(); i++) {
|
||||
int number = 0;
|
||||
for(Object param : replacements) {
|
||||
if(param != null) {
|
||||
if(param instanceof GeneralRegion) {
|
||||
message.set(i, ((GeneralRegion)param).applyAllReplacements(message.get(i)));
|
||||
} else if(param instanceof Message) {
|
||||
Pattern variables = Pattern.compile(Pattern.quote(VARIABLESTART)+number+Pattern.quote(VARIABLEEND));
|
||||
Matcher matches = variables.matcher(message.get(i));
|
||||
if(matches.find()) { // Only replaces one occurance of the variable, others will be done next round
|
||||
int startDiff = message.size()-i;
|
||||
List<String> insertMessage = ((Message)param).get(limit);
|
||||
if(limit.reached()) {
|
||||
return;
|
||||
}
|
||||
FancyMessageFormat.insertMessage(message, insertMessage, i, matches.start(), matches.end());
|
||||
// Skip to end of insert
|
||||
i = message.size()-startDiff;
|
||||
}
|
||||
number++;
|
||||
} else {
|
||||
message.set(i, message.get(i).replace(VARIABLESTART+number+VARIABLEEND, param.toString()));
|
||||
number++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all language variables in a message
|
||||
*/
|
||||
private void replaceLanguageVariables(Limit limit) {
|
||||
if(message == null || message.size() == 0 || limit.reached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pattern variables = Pattern.compile(
|
||||
Pattern.quote(VARIABLESTART)+
|
||||
Pattern.quote(LANGUAGEVARIABLE)+"[a-zA-Z-]+"+ // Language key
|
||||
"(\\|(.*?\\|)+)?"+ // Optional message arguments
|
||||
Pattern.quote(VARIABLEEND)
|
||||
);
|
||||
|
||||
for(int i = 0; i < message.size(); i++) {
|
||||
Matcher matches = variables.matcher(message.get(i));
|
||||
if(matches.find()) {
|
||||
String variable = matches.group();
|
||||
String key;
|
||||
Object[] arguments = null;
|
||||
if(variable.contains("|")) {
|
||||
key = variable.substring(6, variable.indexOf("|"));
|
||||
arguments = variable.substring(variable.indexOf("|")+1, variable.length()-1).split("\\|");
|
||||
} else {
|
||||
key = variable.substring(6, variable.length()-1);
|
||||
}
|
||||
Message insert = Message.fromKey(key);
|
||||
if(arguments != null) {
|
||||
insert.replacements(arguments);
|
||||
}
|
||||
|
||||
// Insert message
|
||||
int startDiff = message.size()-i;
|
||||
List<String> insertMessage = insert.get(limit);
|
||||
if(limit.reached()) {
|
||||
return;
|
||||
}
|
||||
FancyMessageFormat.insertMessage(message, insertMessage, i, matches.start(), matches.end());
|
||||
// Skip to end of insert
|
||||
i = message.size()-startDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Message(key:"+key+", message:"+message+")";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class to store a limit
|
||||
*/
|
||||
private class Limit {
|
||||
public int left = 0;
|
||||
public boolean notified = false;
|
||||
public Message message;
|
||||
|
||||
/**
|
||||
* Set the initial limit
|
||||
* @param count The limit to use
|
||||
*/
|
||||
public Limit(int count, Message message) {
|
||||
left = count;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the limit is reached
|
||||
* @return true if the limit is reached, otherwise false
|
||||
*/
|
||||
public boolean reached() {
|
||||
return left <= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package me.wiefferink.areashop.messages;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class Transifex {
|
||||
public static boolean convertFrom(File inputFile) {
|
||||
if(inputFile == null || !inputFile.exists() || !inputFile.isFile()) {
|
||||
warn("Could not convert Transifix file, it does not exist");
|
||||
return false;
|
||||
}
|
||||
AreaShop.debug("Transifex conversion of", inputFile.getAbsolutePath());
|
||||
|
||||
File newFile = new File(inputFile.getAbsolutePath()+".new");
|
||||
try(
|
||||
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(newFile))
|
||||
) {
|
||||
// Create target file
|
||||
newFile.createNewFile();
|
||||
|
||||
// Add translation strings
|
||||
String line = reader.readLine();
|
||||
boolean first = true;
|
||||
String lastLineStart = null;
|
||||
while(line != null) {
|
||||
// Skip line with the language on it
|
||||
if(first) {
|
||||
first = false;
|
||||
line = reader.readLine();
|
||||
continue;
|
||||
}
|
||||
// Skip comment lines (normally there are none)
|
||||
if(line.startsWith("#")) {
|
||||
line = reader.readLine();
|
||||
continue;
|
||||
}
|
||||
// Strip whitespace at the front
|
||||
if(line.length() > 2) {
|
||||
line = line.substring(2);
|
||||
}
|
||||
// Add empty lines between messages of a different type (the part before - decides the type)
|
||||
if(lastLineStart != null && !line.trim().isEmpty() && !line.startsWith(lastLineStart) && !line.trim().startsWith("-")) {
|
||||
writer.newLine();
|
||||
}
|
||||
// Write line to the new file
|
||||
if(!line.trim().isEmpty()) {
|
||||
// Detect special fancyformat lines
|
||||
if(line.contains("\\n")) {
|
||||
String[] specials = line.split("\\\\n");
|
||||
//print("Contains newline: "+line+", split into "+specials.length+" parts");
|
||||
// Write identifier
|
||||
writer.write(specials[0].substring(0, specials[0].indexOf(":")+1));
|
||||
writer.newLine();
|
||||
// Strip identifier from first part
|
||||
specials[0] = specials[0].substring(specials[0].indexOf(":")+3);
|
||||
// Write special lines
|
||||
for(String special : specials) {
|
||||
writer.write(" - \"");
|
||||
if(special.startsWith("\\t")) {
|
||||
special = special.substring(2);
|
||||
writer.write(" ");
|
||||
}
|
||||
writer.write(special);
|
||||
if(!special.endsWith("\"")) {
|
||||
writer.write("\"");
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
} else {
|
||||
// Simply copy the line
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
// Update last line start
|
||||
String[] splittedLine = line.split("-");
|
||||
if(splittedLine.length > 0 && !line.trim().isEmpty()) {
|
||||
lastLineStart = splittedLine[0];
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
} catch(IOException e) {
|
||||
warn("Could not convert Transifix file:", ExceptionUtils.getStackTrace(e));
|
||||
newFile.delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move current file to .old, move new file to original location
|
||||
File oldFile = new File(inputFile.getAbsolutePath()+".transifex");
|
||||
if(oldFile.exists() && oldFile.isFile()) {
|
||||
if(!oldFile.delete()) {
|
||||
warn("Could not remove existing old file:", oldFile.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(!inputFile.renameTo(oldFile)) {
|
||||
warn("Could not move input file to .old, from", inputFile.getAbsolutePath(), "to", oldFile.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
if(!newFile.renameTo(inputFile)) {
|
||||
warn("Could not move new file to original file location, from", newFile.getAbsolutePath(), "to", inputFile.getAbsolutePath());
|
||||
oldFile.renameTo(inputFile); // Try to recover original file
|
||||
return false;
|
||||
}
|
||||
AreaShop.info("Converted "+inputFile.getName()+" from the Transifex layout to the AreaShop layout, original saved in "+oldFile.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a warning to the console
|
||||
* @param message The message to print
|
||||
*/
|
||||
private static void warn(String... message) {
|
||||
AreaShop.warn("[Transifex language file conversion]", StringUtils.join(message, " "));
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package me.wiefferink.areashop.regions;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.Utils;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@@ -16,538 +16,471 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BuyRegion extends GeneralRegion {
|
||||
public class BuyRegion extends TransactionalRegion {
|
||||
|
||||
public BuyRegion(AreaShop plugin, YamlConfiguration config) {
|
||||
super(plugin, config);
|
||||
}
|
||||
|
||||
public BuyRegion(AreaShop plugin, String name, World world) {
|
||||
super(plugin, name, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionType getType() {
|
||||
return RegionType.BUY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionState getState() {
|
||||
if(isSold() && isInResellingMode()) {
|
||||
return RegionState.RESELL;
|
||||
} else if(isSold() && !isInResellingMode()) {
|
||||
return RegionState.SOLD;
|
||||
} else {
|
||||
return RegionState.FORSALE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UUID of the owner of this region
|
||||
* @return The UUID of the owner of this region
|
||||
*/
|
||||
public UUID getBuyer() {
|
||||
String buyer = config.getString("buy.buyer");
|
||||
if(buyer != null) {
|
||||
try {
|
||||
return UUID.fromString(buyer);
|
||||
} catch(IllegalArgumentException e) {
|
||||
// Incorrect UUID
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player is the buyer of this region
|
||||
* @param player Player to check
|
||||
* @return true if this player owns this region, otherwise false
|
||||
*/
|
||||
public boolean isBuyer(Player player) {
|
||||
return player != null && isBuyer(player.getUniqueId());
|
||||
}
|
||||
public boolean isBuyer(UUID player) {
|
||||
UUID buyer = getBuyer();
|
||||
return !(buyer == null || player == null) && buyer.equals(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buyer of this region
|
||||
* @param buyer The UUID of the player that should be set as buyer
|
||||
*/
|
||||
public void setBuyer(UUID buyer) {
|
||||
if(buyer == null) {
|
||||
setSetting("buy.buyer", null);
|
||||
setSetting("buy.buyerName", null);
|
||||
} else {
|
||||
setSetting("buy.buyer", buyer.toString());
|
||||
setSetting("buy.buyerName", Utils.toName(buyer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the player that owns this region
|
||||
* @return The name of the player that owns this region, if unavailable by UUID it will return the old cached name, if that is unavailable it will return <UNKNOWN>
|
||||
*/
|
||||
public String getPlayerName() {
|
||||
String result = Utils.toName(getBuyer());
|
||||
if(result == null || result.isEmpty()) {
|
||||
result = getStringSetting("buy.buyerName");
|
||||
if(result == null || result.isEmpty()) {
|
||||
result = "<UNKNOWN>";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region is sold
|
||||
* @return true if the region is sold, otherwise false
|
||||
*/
|
||||
public boolean isSold() {
|
||||
return getBuyer() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region is being resold
|
||||
* @return true if the region is available for reselling, otherwise false
|
||||
*/
|
||||
public boolean isInResellingMode() {
|
||||
return config.getBoolean("buy.resellMode");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price of the region
|
||||
* @return The price of the region
|
||||
*/
|
||||
public double getPrice() {
|
||||
return getDoubleSetting("buy.price");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resell price of this region
|
||||
* @return The resell price if isInResellingMode(), otherwise 0.0
|
||||
*/
|
||||
public double getResellPrice() {
|
||||
return config.getDouble("buy.resellPrice");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the price (includes prefix and suffix)
|
||||
* @return The formatted string of the price
|
||||
*/
|
||||
public String getFormattedPrice() {
|
||||
return Utils.formatCurrency(getPrice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the resellprice (includes prefix and suffix)
|
||||
* @return The formatted string of the resellprice
|
||||
*/
|
||||
public String getFormattedResellPrice() {
|
||||
return Utils.formatCurrency(getResellPrice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the price of the region
|
||||
* @param price The price to set this region to
|
||||
*/
|
||||
public void setPrice(double price) {
|
||||
setSetting("buy.price", price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the price so that the price will be taken from a group or the default.yml file
|
||||
*/
|
||||
public void removePrice() {
|
||||
setSetting("buy.price", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region into resell mode with the given price
|
||||
* @param price The price this region should be put up for sale
|
||||
*/
|
||||
public void enableReselling(double price) {
|
||||
setSetting("buy.resellMode", true);
|
||||
setSetting("buy.resellPrice", price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop this region from being in resell mode
|
||||
*/
|
||||
public void disableReselling() {
|
||||
setSetting("buy.resellMode", null);
|
||||
setSetting("buy.resellPrice", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the moneyBack percentage
|
||||
* @return The % of money the player will get back when selling
|
||||
*/
|
||||
public double getMoneyBackPercentage() {
|
||||
return getDoubleSetting("buy.moneyBack");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of money that should be paid to the player when selling the region
|
||||
* @return The amount of money the player should get back
|
||||
*/
|
||||
public double getMoneyBackAmount() {
|
||||
return getPrice() * (getMoneyBackPercentage() / 100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the amount of the moneyBack amount
|
||||
* @return String with currency symbols and proper fractional part
|
||||
*/
|
||||
public String getFormattedMoneyBackAmount() {
|
||||
return Utils.formatCurrency(getMoneyBackAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, Object> getSpecificReplacements() {
|
||||
// Fill the replacements map with things specific to a BuyRegion
|
||||
HashMap<String, Object> result = new HashMap<>();
|
||||
result.put(AreaShop.tagPrice, getFormattedPrice());
|
||||
result.put(AreaShop.tagRawPrice, getPrice());
|
||||
result.put(AreaShop.tagPlayerName, getPlayerName());
|
||||
result.put(AreaShop.tagPlayerUUID, getBuyer());
|
||||
result.put(AreaShop.tagResellPrice, getFormattedResellPrice());
|
||||
result.put(AreaShop.tagRawResellPrice, getResellPrice());
|
||||
result.put(AreaShop.tagMoneyBackAmount, getFormattedMoneyBackAmount());
|
||||
result.put(AreaShop.tagRawMoneyBackAmount, getMoneyBackAmount());
|
||||
double moneyBackPercent = getMoneyBackPercentage();
|
||||
if((moneyBackPercent%1.0) == 0.0) {
|
||||
result.put(AreaShop.tagMoneyBackPercentage, (int)moneyBackPercent);
|
||||
} else {
|
||||
result.put(AreaShop.tagMoneyBackPercentage, moneyBackPercent);
|
||||
}
|
||||
result.put(AreaShop.tagMaxInactiveTime, this.getFormattedInactiveTimeUntilSell());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minutes until automatic unrent when player is offline
|
||||
* @return The number of milliseconds until the region is unrented while player is offline
|
||||
*/
|
||||
public long getInactiveTimeUntilSell() {
|
||||
return Utils.getDurationFromMinutesOrStringInput(getStringSetting("buy.inactiveTimeUntilSell"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a human readable string indicating how long the player can be offline until automatic unrent
|
||||
* @return String indicating the inactive time until unrent
|
||||
*/
|
||||
public String getFormattedInactiveTimeUntilSell() {
|
||||
return Utils.millisToHumanFormat(getInactiveTimeUntilSell());
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy a region
|
||||
* @param player The player that wants to buy the region
|
||||
* @return true if it succeeded and false if not
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean buy(Player player) {
|
||||
// Check if the player has permission
|
||||
if(player.hasPermission("areashop.buy")) {
|
||||
if(plugin.getEconomy() == null) {
|
||||
message(player, "general-noEconomy");
|
||||
return false;
|
||||
}
|
||||
if(isInResellingMode()) {
|
||||
if(!player.hasPermission("areashop.buyresell")) {
|
||||
message(player, "buy-noPermissionResell");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!player.hasPermission("areashop.buynormal")) {
|
||||
message(player, "buy-noPermissionNoResell");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(getWorld() == null) {
|
||||
message(player, "general-noWorld");
|
||||
return false;
|
||||
}
|
||||
if(getRegion() == null) {
|
||||
message(player, "general-noRegion");
|
||||
return false;
|
||||
}
|
||||
if(!isSold() || (isInResellingMode() && !isBuyer(player))) {
|
||||
boolean isResell = isInResellingMode();
|
||||
// Check if the players needs to be in the world or region for buying
|
||||
if(restrictedToRegion() && (!player.getWorld().getName().equals(getWorldName())
|
||||
|| !getRegion().contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
|
||||
message(player, "buy-restrictedToRegion");
|
||||
return false;
|
||||
}
|
||||
if(restrictedToWorld() && !player.getWorld().getName().equals(getWorldName())) {
|
||||
message(player, "buy-restrictedToWorld", player.getWorld().getName());
|
||||
return false;
|
||||
}
|
||||
// Check region limits
|
||||
LimitResult limitResult = this.limitsAllow(RegionType.BUY, player);
|
||||
AreaShop.debug("LimitResult: " + limitResult.toString());
|
||||
if(!limitResult.actionAllowed()) {
|
||||
if(limitResult.getLimitingFactor() == LimitType.TOTAL) {
|
||||
message(player, "total-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
if(limitResult.getLimitingFactor() == LimitType.BUYS) {
|
||||
message(player, "buy-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
// Should not be reached, but is safe like this
|
||||
return false;
|
||||
}
|
||||
private static final String UNKNOWN_BUYER = "<UNKNOWN>";
|
||||
|
||||
// Check if the player has enough money
|
||||
if((!isResell && plugin.getEconomy().has(player, getWorldName(), getPrice())) || (isResell && plugin.getEconomy().has(player, getWorldName(), getResellPrice()))) {
|
||||
UUID oldOwner = getBuyer();
|
||||
if(isResell && oldOwner != null) {
|
||||
// Broadcast and check event
|
||||
ResellingRegionEvent event = new ResellingRegionEvent(this, player);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(player, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
public BuyRegion(YamlConfiguration config) {
|
||||
super(config, RegionType.BUY);
|
||||
}
|
||||
|
||||
getFriendsFeature().clearFriends();
|
||||
double resellPrice = getResellPrice();
|
||||
// Transfer the money to the previous owner
|
||||
EconomyResponse r = plugin.getEconomy().withdrawPlayer(player, getWorldName(), getResellPrice());
|
||||
if(!r.transactionSuccess()) {
|
||||
message(player, "buy-payError");
|
||||
AreaShop.debug("Something went wrong with getting money from " + player.getName() + " while buying " + getName() + ": " + r.errorMessage);
|
||||
return false;
|
||||
}
|
||||
r = null;
|
||||
OfflinePlayer oldOwnerPlayer = Bukkit.getOfflinePlayer(oldOwner);
|
||||
String oldOwnerName = getPlayerName();
|
||||
if(oldOwnerPlayer != null && oldOwnerPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().depositPlayer(oldOwnerPlayer, getWorldName(), getResellPrice());
|
||||
oldOwnerName = oldOwnerPlayer.getName();
|
||||
} else if (oldOwnerName != null) {
|
||||
r = plugin.getEconomy().depositPlayer(oldOwnerName, getWorldName(), getResellPrice());
|
||||
}
|
||||
if(r == null || !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '"+oldOwnerName+"' "+getFormattedPrice()+" for his resell of region "+getName()+" to "+player.getName());
|
||||
}
|
||||
// Resell is done, disable that now
|
||||
disableReselling();
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.RESELL, true);
|
||||
// Set the owner
|
||||
setBuyer(player.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
public BuyRegion(String name, World world) {
|
||||
super(name, world, RegionType.BUY);
|
||||
}
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.RESELL);
|
||||
@Override
|
||||
public RegionState getState() {
|
||||
if (isSold() && isInResellingMode()) {
|
||||
return RegionState.RESELL;
|
||||
} else if (isSold() && !isInResellingMode()) {
|
||||
return RegionState.SOLD;
|
||||
} else {
|
||||
return RegionState.FORSALE;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new ResoldRegionEvent(this, oldOwner));
|
||||
/**
|
||||
* Get the UUID of the owner of this region.
|
||||
*
|
||||
* @return The UUID of the owner of this region
|
||||
*/
|
||||
@Deprecated
|
||||
public UUID getBuyer() {
|
||||
String buyer = config.getString("buy.buyer");
|
||||
if (buyer != null) {
|
||||
try {
|
||||
return UUID.fromString(buyer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Incorrect UUID
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Send message to the player
|
||||
message(player, "buy-successResale", oldOwnerName);
|
||||
Player seller = Bukkit.getPlayer(oldOwner);
|
||||
if(seller != null) {
|
||||
message(seller, "buy-successSeller", resellPrice);
|
||||
}
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.RESELL, false);
|
||||
} else {
|
||||
// Broadcast and check event
|
||||
BuyingRegionEvent event = new BuyingRegionEvent(this, player);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(player, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Set the buyer of this region.
|
||||
*
|
||||
* @param buyer The UUID of the player that should be set as buyer
|
||||
*/
|
||||
@Deprecated
|
||||
public void setBuyer(UUID buyer) {
|
||||
if (buyer == null) {
|
||||
setSetting("buy.buyer", null);
|
||||
setSetting("buy.buyerName", null);
|
||||
} else {
|
||||
setSetting("buy.buyer", buyer.toString());
|
||||
setSetting("buy.buyerName", Utils.toName(buyer));
|
||||
}
|
||||
this.setTransactionHolder(buyer);
|
||||
}
|
||||
|
||||
// Substract the money from the players balance
|
||||
EconomyResponse r = plugin.getEconomy().withdrawPlayer(player, getWorldName(), getPrice());
|
||||
if(!r.transactionSuccess()) {
|
||||
message(player, "buy-payError");
|
||||
return false;
|
||||
}
|
||||
// Optionally give money to the landlord
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if(getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
if(landlordName != null) {
|
||||
if(landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().depositPlayer(landlordPlayer, getWorldName(), getPrice());
|
||||
} else {
|
||||
r = plugin.getEconomy().depositPlayer(landlordName, getWorldName(), getPrice());
|
||||
}
|
||||
if(r != null && !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '"+landlordName+"' "+getFormattedPrice()+" for his sell of region "+getName()+" to "+player.getName());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if a player is the buyer of this region.
|
||||
*
|
||||
* @param player Player to check
|
||||
* @return true if this player owns this region, otherwise false
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isBuyer(OfflinePlayer player) {
|
||||
return player != null && isBuyer(player.getUniqueId());
|
||||
}
|
||||
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.BOUGHT, true);
|
||||
// Set the owner
|
||||
setBuyer(player.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
@Deprecated
|
||||
public boolean isBuyer(UUID player) {
|
||||
UUID buyer = getBuyer();
|
||||
return !(buyer == null || player == null) && buyer.equals(player);
|
||||
}
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new BoughtRegionEvent(this));
|
||||
/**
|
||||
* Get the name of the player that owns this region.
|
||||
*
|
||||
* @return The name of the player that owns this region, if unavailable by UUID it will return the old cached name, if that is unavailable it will return <UNKNOWN>
|
||||
*/
|
||||
public String getPlayerName() {
|
||||
String result = Utils.toName(getBuyer());
|
||||
if (result.isEmpty()) {
|
||||
result = getStringSetting("buy.buyerName");
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = UNKNOWN_BUYER;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.BOUGHT);
|
||||
/**
|
||||
* Check if the region is being resold.
|
||||
*
|
||||
* @return true if the region is available for reselling, otherwise false
|
||||
*/
|
||||
public boolean isInResellingMode() {
|
||||
return config.getBoolean("buy.resellMode");
|
||||
}
|
||||
|
||||
// Send message to the player
|
||||
message(player, "buy-succes");
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.BOUGHT, false);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// Player has not enough money
|
||||
if(isResell) {
|
||||
message(player, "buy-lowMoneyResell", Utils.formatCurrency(plugin.getEconomy().getBalance(player, getWorldName())));
|
||||
} else {
|
||||
message(player, "buy-lowMoney", Utils.formatCurrency(plugin.getEconomy().getBalance(player, getWorldName())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(isBuyer(player)) {
|
||||
message(player, "buy-yours");
|
||||
} else {
|
||||
message(player, "buy-someoneElse");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
message(player, "buy-noPermission");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sell a buyed region, get part of the money back
|
||||
* @param giveMoneyBack true if the player should be given money back, otherwise false
|
||||
* @param executor CommandSender to receive a message when the sell fails, or null
|
||||
* @return true if the region has been sold, otherwise false
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean sell(boolean giveMoneyBack, CommandSender executor) {
|
||||
boolean own = executor != null && executor instanceof Player && this.isBuyer((Player)executor);
|
||||
if(executor != null) {
|
||||
if(!executor.hasPermission("areashop.sell") && !own) {
|
||||
message(executor, "sell-noPermissionOther");
|
||||
return false;
|
||||
}
|
||||
if(!executor.hasPermission("areashop.sell") && !executor.hasPermission("areashop.sellown") && own) {
|
||||
message(executor, "sell-noPermission");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the resell price of this region.
|
||||
*
|
||||
* @return The resell price if isInResellingMode(), otherwise 0.0
|
||||
*/
|
||||
public double getResellPrice() {
|
||||
return Math.max(0, config.getDouble("buy.resellPrice"));
|
||||
}
|
||||
|
||||
if(plugin.getEconomy() == null) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Get the formatted string of the resellprice (includes prefix and suffix).
|
||||
*
|
||||
* @return The formatted string of the resellprice
|
||||
*/
|
||||
public String getFormattedResellPrice() {
|
||||
return Utils.formatCurrency(getResellPrice());
|
||||
}
|
||||
|
||||
// Broadcast and check event
|
||||
SellingRegionEvent event = new SellingRegionEvent(this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(executor, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Set the region into resell mode with the given price.
|
||||
*
|
||||
* @param price The price this region should be put up for sale
|
||||
*/
|
||||
public void enableReselling(double price) {
|
||||
setSetting("buy.resellMode", true);
|
||||
setSetting("buy.resellPrice", price);
|
||||
}
|
||||
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.SOLD, true);
|
||||
|
||||
disableReselling();
|
||||
// Give part of the buying price back
|
||||
double moneyBack = getMoneyBackAmount();
|
||||
if(moneyBack > 0 && giveMoneyBack) {
|
||||
boolean noPayBack = false;
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if(getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
EconomyResponse r;
|
||||
if(landlordName != null) {
|
||||
if(landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().withdrawPlayer(landlordPlayer, getWorldName(), moneyBack);
|
||||
} else {
|
||||
r = plugin.getEconomy().withdrawPlayer(landlordName, getWorldName(), moneyBack);
|
||||
}
|
||||
if(r == null || !r.transactionSuccess()) {
|
||||
noPayBack = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Give back the money
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
|
||||
if(player != null && !noPayBack) {
|
||||
EconomyResponse response = null;
|
||||
boolean error = false;
|
||||
try {
|
||||
if(player.getName() != null) {
|
||||
response = plugin.getEconomy().depositPlayer(player, getWorldName(), moneyBack);
|
||||
} else if(getPlayerName() != null) {
|
||||
response = plugin.getEconomy().depositPlayer(getPlayerName(), getWorldName(), moneyBack);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
error = true;
|
||||
}
|
||||
if(error || response == null || !response.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying back money to "+getPlayerName()+" while selling region "+getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stop this region from being in resell mode.
|
||||
*/
|
||||
public void disableReselling() {
|
||||
setSetting("buy.resellMode", null);
|
||||
setSetting("buy.resellPrice", null);
|
||||
}
|
||||
|
||||
message(executor, "sell-sold");
|
||||
@Override
|
||||
public Object provideReplacement(String variable) {
|
||||
switch (variable) {
|
||||
case AreaShop.tagResellPrice:
|
||||
return getFormattedResellPrice();
|
||||
case AreaShop.tagRawResellPrice:
|
||||
return getResellPrice();
|
||||
default:
|
||||
return super.provideReplacement(variable);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove friends and the owner
|
||||
getFriendsFeature().clearFriends();
|
||||
UUID oldBuyer = getBuyer();
|
||||
setBuyer(null);
|
||||
removeLastActiveTime();
|
||||
/**
|
||||
* Minutes until automatic unrent when player is offline.
|
||||
*
|
||||
* @return The number of milliseconds until the region is unrented while player is offline
|
||||
*/
|
||||
@Deprecated
|
||||
public long getInactiveTimeUntilSell() {
|
||||
return Utils.getDurationFromMinutesOrStringInput(getStringSetting("buy.inactiveTimeUntilSell"));
|
||||
}
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new SoldRegionEvent(this, oldBuyer, Math.max(moneyBack, 0)));
|
||||
/**
|
||||
* Get a human readable string indicating how long the player can be offline until automatic unrent.
|
||||
*
|
||||
* @return String indicating the inactive time until unrent
|
||||
*/
|
||||
@Deprecated
|
||||
public String getFormattedInactiveTimeUntilSell() {
|
||||
return Utils.millisToHumanFormat(getInactiveTimeUntilSell());
|
||||
}
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.SOLD);
|
||||
/**
|
||||
* Buy a region.
|
||||
*
|
||||
* @param offlinePlayer The player that wants to buy the region
|
||||
* @return true if it succeeded and false if not
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean buy(OfflinePlayer offlinePlayer) {
|
||||
// Check if the player has permission
|
||||
if (!plugin.hasPermission(offlinePlayer, "areashop.buy")) {
|
||||
message(offlinePlayer, "buy-noPermission");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Run commands
|
||||
this.runEventCommands(RegionEvent.SOLD, false);
|
||||
return true;
|
||||
}
|
||||
if (plugin.getEconomy() == null) {
|
||||
message(offlinePlayer, "general-noEconomy");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInactive() {
|
||||
if(isDeleted() || !isSold()) {
|
||||
return false;
|
||||
}
|
||||
long inactiveSetting = getInactiveTimeUntilSell();
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
|
||||
if(inactiveSetting <= 0 || player.isOp()) {
|
||||
return false;
|
||||
}
|
||||
long lastPlayed = getLastActiveTime();
|
||||
//AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis()-player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
|
||||
if(Calendar.getInstance().getTimeInMillis() > (lastPlayed + inactiveSetting)) {
|
||||
AreaShop.info("Region "+getName()+" unrented because of inactivity for player "+getPlayerName());
|
||||
AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis()-player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
|
||||
return this.sell(true, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (isInResellingMode()) {
|
||||
if (!plugin.hasPermission(offlinePlayer, "areashop.buyresell")) {
|
||||
message(offlinePlayer, "buy-noPermissionResell");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!plugin.hasPermission(offlinePlayer, "areashop.buynormal")) {
|
||||
message(offlinePlayer, "buy-noPermissionNoResell");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (getWorld() == null) {
|
||||
message(offlinePlayer, "general-noWorld");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getRegion() == null) {
|
||||
message(offlinePlayer, "general-noRegion");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSold() && !(isInResellingMode() && !isBuyer(offlinePlayer))) {
|
||||
if (isBuyer(offlinePlayer)) {
|
||||
message(offlinePlayer, "buy-yours");
|
||||
} else {
|
||||
message(offlinePlayer, "buy-someoneElse");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isResell = isInResellingMode();
|
||||
|
||||
// Only relevant if the player is online
|
||||
Player player = offlinePlayer.getPlayer();
|
||||
if (player != null) {
|
||||
// Check if the players needs to be in the region for buying
|
||||
if (restrictedToRegion() && (!player.getWorld().getName().equals(getWorldName())
|
||||
|| !getRegion().contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
|
||||
message(offlinePlayer, "buy-restrictedToRegion");
|
||||
return false;
|
||||
}
|
||||
// Check if the players needs to be in the world for buying
|
||||
if (restrictedToWorld() && !player.getWorld().getName().equals(getWorldName())) {
|
||||
message(offlinePlayer, "buy-restrictedToWorld", player.getWorld().getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check region limits
|
||||
LimitResult limitResult = this.limitsAllow(RegionType.BUY, offlinePlayer);
|
||||
AreaShop.debug("LimitResult: " + limitResult.toString());
|
||||
if (!limitResult.actionAllowed()) {
|
||||
if (limitResult.getLimitingFactor() == LimitType.TOTAL) {
|
||||
message(offlinePlayer, "total-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
if (limitResult.getLimitingFactor() == LimitType.BUYS) {
|
||||
message(offlinePlayer, "buy-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
// Should not be reached, but is safe like this
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the player has enough money
|
||||
if (isResell && !plugin.getEconomy().has(offlinePlayer, getWorldName(), getResellPrice())) {
|
||||
message(offlinePlayer, "buy-lowMoneyResell", Utils.formatCurrency(plugin.getEconomy().getBalance(offlinePlayer, getWorldName())));
|
||||
return false;
|
||||
}
|
||||
if (!isResell && !plugin.getEconomy().has(offlinePlayer, getWorldName(), getPrice())) {
|
||||
message(offlinePlayer, "buy-lowMoney", Utils.formatCurrency(plugin.getEconomy().getBalance(offlinePlayer, getWorldName())));
|
||||
return false;
|
||||
}
|
||||
|
||||
UUID oldOwner = getBuyer();
|
||||
if (isResell && oldOwner != null) {
|
||||
// Broadcast and check event
|
||||
ResellingRegionEvent event = new ResellingRegionEvent(this, offlinePlayer);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
message(offlinePlayer, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
getFriendsFeature().clearFriends();
|
||||
double resellPrice = getResellPrice();
|
||||
// Transfer the money to the previous owner
|
||||
EconomyResponse r = plugin.getEconomy().withdrawPlayer(offlinePlayer, getWorldName(), getResellPrice());
|
||||
if (!r.transactionSuccess()) {
|
||||
message(offlinePlayer, "buy-payError");
|
||||
AreaShop.debug("Something went wrong with getting money from " + offlinePlayer.getName() + " while buying " + getName() + ": " + r.errorMessage);
|
||||
return false;
|
||||
}
|
||||
r = null;
|
||||
OfflinePlayer oldOwnerPlayer = Bukkit.getOfflinePlayer(oldOwner);
|
||||
String oldOwnerName = getPlayerName();
|
||||
if (oldOwnerPlayer.hasPlayedBefore() && oldOwnerPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().depositPlayer(oldOwnerPlayer, getWorldName(), getResellPrice());
|
||||
oldOwnerName = oldOwnerPlayer.getName();
|
||||
} else if (oldOwnerName != null) {
|
||||
r = plugin.getEconomy().depositPlayer(oldOwnerName, getWorldName(), getResellPrice());
|
||||
}
|
||||
if (r == null || !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '" + oldOwnerName + "' " + getFormattedPrice() + " for his resell of region " + getName() + " to " + offlinePlayer.getName());
|
||||
}
|
||||
// Resell is done, disable that now
|
||||
disableReselling();
|
||||
|
||||
// Set the owner
|
||||
setBuyer(offlinePlayer.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.RESELL);
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new ResoldRegionEvent(this, oldOwner));
|
||||
|
||||
// Send message to the player
|
||||
message(offlinePlayer, "buy-successResale", oldOwnerName);
|
||||
Player seller = Bukkit.getPlayer(oldOwner);
|
||||
if (seller != null) {
|
||||
message(seller, "buy-successSeller", resellPrice);
|
||||
}
|
||||
} else {
|
||||
// Broadcast and check event
|
||||
BuyingRegionEvent event = new BuyingRegionEvent(this, offlinePlayer);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
message(offlinePlayer, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Substract the money from the players balance
|
||||
EconomyResponse r = plugin.getEconomy().withdrawPlayer(offlinePlayer, getWorldName(), getPrice());
|
||||
if (!r.transactionSuccess()) {
|
||||
message(offlinePlayer, "buy-payError");
|
||||
return false;
|
||||
}
|
||||
// Optionally give money to the landlord
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if (getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
if (landlordName != null) {
|
||||
if (landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().depositPlayer(landlordPlayer, getWorldName(), getPrice());
|
||||
} else {
|
||||
r = plugin.getEconomy().depositPlayer(landlordName, getWorldName(), getPrice());
|
||||
}
|
||||
if (r != null && !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '" + landlordName + "' " + getFormattedPrice() + " for his sell of region " + getName() + " to " + offlinePlayer.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Set the owner
|
||||
setBuyer(offlinePlayer.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
|
||||
// Send message to the player
|
||||
message(offlinePlayer, "buy-succes");
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.BOUGHT);
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new BoughtRegionEvent(this));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sell a purchased region, get part of the money back.
|
||||
*
|
||||
* @param giveMoneyBack true if the player should be given money back, otherwise false
|
||||
* @param executor CommandSender to receive a message when the sell fails, or null
|
||||
* @return true if the region has been sold, otherwise false
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean sell(boolean giveMoneyBack, CommandSender executor) {
|
||||
boolean own = executor instanceof Player && this.isBuyer((Player) executor);
|
||||
if (executor != null) {
|
||||
if (!executor.hasPermission("areashop.sell") && !own) {
|
||||
message(executor, "sell-noPermissionOther");
|
||||
return false;
|
||||
}
|
||||
if (!executor.hasPermission("areashop.sell") && !executor.hasPermission("areashop.sellown") && own) {
|
||||
message(executor, "sell-noPermission");
|
||||
return false;
|
||||
}
|
||||
if (!executor.hasPermission("areashop.sell")
|
||||
&& executor.hasPermission("areashop.sellown")
|
||||
&& own
|
||||
&& getBooleanSetting("buy.sellDisabled")) {
|
||||
message(executor, "sell-disabled");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getEconomy() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Broadcast and check event
|
||||
SellingRegionEvent event = new SellingRegionEvent(this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
message(executor, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
disableReselling();
|
||||
// Give part of the buying price back
|
||||
double moneyBack = getMoneyBackAmount();
|
||||
if (moneyBack > 0 && giveMoneyBack) {
|
||||
boolean noPayBack = false;
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if (getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
EconomyResponse r;
|
||||
if (landlordName != null) {
|
||||
if (landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().withdrawPlayer(landlordPlayer, getWorldName(), moneyBack);
|
||||
} else {
|
||||
r = plugin.getEconomy().withdrawPlayer(landlordName, getWorldName(), moneyBack);
|
||||
}
|
||||
if (r == null || !r.transactionSuccess()) {
|
||||
noPayBack = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Give back the money
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(getTransactionHolder());
|
||||
if (player.hasPlayedBefore() && !noPayBack) {
|
||||
EconomyResponse response = null;
|
||||
boolean error = false;
|
||||
try {
|
||||
if (player.getName() != null) {
|
||||
response = plugin.getEconomy().depositPlayer(player, getWorldName(), moneyBack);
|
||||
} else if (getPlayerName() != null) {
|
||||
response = plugin.getEconomy().depositPlayer(getPlayerName(), getWorldName(), moneyBack);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error = true;
|
||||
}
|
||||
if (error || response == null || !response.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying back money to " + getPlayerName() + " while selling region " + getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle schematic save/restore (while %uuid% is still available)
|
||||
handleSchematicEvent(RegionEvent.SOLD);
|
||||
|
||||
// Send message: before actual removal of the buyer so that it is still available for variables
|
||||
message(executor, "sell-sold");
|
||||
|
||||
// Remove friends and the owner
|
||||
getFriendsFeature().clearFriends();
|
||||
UUID oldBuyer = getBuyer();
|
||||
setBuyer(null);
|
||||
removeLastActiveTime();
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new SoldRegionEvent(this, oldBuyer, Math.max(moneyBack, 0)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleInactivity() {
|
||||
return this.sell(true, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,7 @@
|
||||
# Regions
|
||||
|
||||
This package contains the `GeneralRegion` class which represents a region in AreaShop. Such a region is linked to a WorldGuard region and has its own configuration file at `/plugins/AreaShop/regions/<name>.yml`.
|
||||
|
||||
The `BuyRegion` and `RentRegion` classes represent buy and rental regions (mutually exclusive) and inherit from `GeneralRegion`.
|
||||
|
||||
To group regions there is `RegionGroup`, which allows configuring settings for a lot of regions at once.
|
||||
@@ -2,153 +2,207 @@ package me.wiefferink.areashop.regions;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO consider switching to saving lowercase regions
|
||||
public class RegionGroup {
|
||||
|
||||
private AreaShop plugin;
|
||||
private String name;
|
||||
|
||||
private final AreaShop plugin;
|
||||
private final String name;
|
||||
private final Set<String> regions;
|
||||
private Set<String> autoRegions;
|
||||
private boolean autoDirty;
|
||||
private final Set<String> worlds;
|
||||
|
||||
/**
|
||||
* Constructor, used when creating new groups or restoring them from groups.yml at server boot
|
||||
* Constructor, used when creating new groups or restoring them from groups.yml at server boot.
|
||||
* @param plugin The AreaShop plugin
|
||||
* @param name Name of the group, has to be unique
|
||||
* @param name Name of the group, has to be unique
|
||||
*/
|
||||
public RegionGroup(AreaShop plugin, String name) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.autoDirty = true;
|
||||
setSetting("name", name);
|
||||
// Delete duplicates
|
||||
List<String> members = getMembers();
|
||||
int previousCount = members.size();
|
||||
List<String> newMembers = new ArrayList<>();
|
||||
while(!members.isEmpty()) {
|
||||
String member = members.remove(0);
|
||||
// If the region has been deleted also clean it from the group
|
||||
if(plugin.getFileManager().getRegion(member) != null) {
|
||||
newMembers.add(member);
|
||||
}
|
||||
while(members.contains(member)) {
|
||||
members.remove(member);
|
||||
}
|
||||
}
|
||||
if(newMembers.size() != previousCount) {
|
||||
setSetting("regions", newMembers);
|
||||
AreaShop.debug("group save required because of changed member size");
|
||||
saveRequired();
|
||||
}
|
||||
if(getMembers().size() == 0) {
|
||||
plugin.getFileManager().removeGroup(this);
|
||||
}
|
||||
|
||||
// Load regions and worlds
|
||||
regions = new HashSet<>(getSettings().getStringList("regions"));
|
||||
worlds = new HashSet<>(getSettings().getStringList("worlds"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a member to a group
|
||||
* Get automatically added regions.
|
||||
* @return Set of regions automatically added by the configuration
|
||||
*/
|
||||
public Set<String> getAutoRegions() {
|
||||
if(autoDirty) {
|
||||
autoRegions = new HashSet<>();
|
||||
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
|
||||
if(worlds.contains(region.getWorldName())) {
|
||||
autoRegions.add(region.getName());
|
||||
}
|
||||
}
|
||||
autoDirty = false;
|
||||
}
|
||||
return autoRegions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark that automatically added regions should be regenerated.
|
||||
*/
|
||||
public void autoDirty() {
|
||||
autoDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a world from which all regions should be added to the group.
|
||||
* @param world World from which all regions should be added
|
||||
* @return true if the region was not already added, otherwise false
|
||||
*/
|
||||
public boolean addWorld(String world) {
|
||||
if(worlds.add(world)) {
|
||||
setSetting("regionsFromWorlds", new ArrayList<>(worlds));
|
||||
saveRequired();
|
||||
autoDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a member from the group.
|
||||
* @param world World to remove
|
||||
* @return true if the region was in the group before, otherwise false
|
||||
*/
|
||||
public boolean removeWorld(String world) {
|
||||
if(worlds.remove(world)) {
|
||||
setSetting("regionsFromWorlds", new ArrayList<>(worlds));
|
||||
saveRequired();
|
||||
autoDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all worlds from which regions are added automatically.
|
||||
* @return A list with the names of all worlds (immutable)
|
||||
*/
|
||||
public Set<String> getWorlds() {
|
||||
return new HashSet<>(worlds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member to a group.
|
||||
* @param region The region to add to the group (GeneralRegion or a subclass of it)
|
||||
* @return true if the region was not already added, otherwise false
|
||||
*/
|
||||
public boolean addMember(GeneralRegion region) {
|
||||
List<String> members = getMembers();
|
||||
if(members.contains(region.getLowerCaseName())) {
|
||||
return false;
|
||||
} else {
|
||||
members.add(region.getName());
|
||||
setSetting("regions", members);
|
||||
this.saveRequired();
|
||||
if(regions.add(region.getName())) {
|
||||
setSetting("regions", new ArrayList<>(regions));
|
||||
saveRequired();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a member from the group
|
||||
* Remove a member from the group.
|
||||
* @param region The region to remove
|
||||
* @return true if the region was in the group before, otherwise false
|
||||
*/
|
||||
public boolean removeMember(GeneralRegion region) {
|
||||
List<String> members = getMembers();
|
||||
boolean result = isMember(region);
|
||||
members.remove(region.getName());
|
||||
if(members.isEmpty()) {
|
||||
plugin.getFileManager().removeGroup(this);
|
||||
} else {
|
||||
setSetting("regions", members);
|
||||
}
|
||||
if(result) {
|
||||
this.saveRequired();
|
||||
if(regions.remove(region.getName())) {
|
||||
setSetting("regions", new ArrayList<>(regions));
|
||||
saveRequired();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all members of the group.
|
||||
* @return A list with the names of all members of the group (immutable)
|
||||
*/
|
||||
public Set<String> getMembers() {
|
||||
HashSet<String> result = new HashSet<>(regions);
|
||||
result.addAll(getAutoRegions());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all members of the group
|
||||
* @return A list with the names of all members of the group
|
||||
* Get all manually added members of the group.
|
||||
* @return A list with the names of all members of the group (immutable)
|
||||
*/
|
||||
public List<String> getMembers() {
|
||||
if(getSettings() == null || getSettings().getStringList("regions") == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return getSettings().getStringList("regions");
|
||||
public Set<String> getManualMembers() {
|
||||
return new HashSet<>(regions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all members of the group as GeneralRegions
|
||||
* Get all members of the group as GeneralRegions.
|
||||
* @return A Set with all group members
|
||||
*/
|
||||
public Set<GeneralRegion> getMemberRegions() {
|
||||
Set<GeneralRegion> result = new HashSet<>();
|
||||
for(String name : getMembers()) {
|
||||
result.add(plugin.getFileManager().getRegion(name));
|
||||
for(String playerName : getMembers()) {
|
||||
result.add(plugin.getFileManager().getRegion(playerName));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the group
|
||||
* Get the name of the group.
|
||||
* @return The name of the group
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lowercase name of the group (used for getting the config etc)
|
||||
* Get the lowercase name of the group (used for getting the config etc).
|
||||
* @return The name of the group in lowercase
|
||||
*/
|
||||
public String getLowerCaseName() {
|
||||
return getName().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a region is member of the group
|
||||
* Check if a region is member of the group.
|
||||
* @param region Region to check
|
||||
* @return true if the region is in the group, otherwise false
|
||||
*/
|
||||
public boolean isMember(GeneralRegion region) {
|
||||
return getMembers().contains(region.getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the priority of the group (higher overwrites)
|
||||
* Get the priority of the group (higher overwrites).
|
||||
* @return The priority of the group
|
||||
*/
|
||||
public int getPriority() {
|
||||
return getSettings().getInt("priority");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the configurationsection with the settings of this group
|
||||
* Get the configurationsection with the settings of this group.
|
||||
* @return The ConfigurationSection with the settings of the group
|
||||
*/
|
||||
public ConfigurationSection getSettings() {
|
||||
return plugin.getFileManager().getGroupSettings(name);
|
||||
ConfigurationSection result = plugin.getFileManager().getGroupSettings(name);
|
||||
if(result != null) {
|
||||
return result;
|
||||
} else {
|
||||
return new YamlConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a setting of this group
|
||||
* @param path The path to set
|
||||
* Set a setting of this group.
|
||||
* @param path The path to set
|
||||
* @param setting The value to set
|
||||
*/
|
||||
public void setSetting(String path, Object setting) {
|
||||
@@ -156,14 +210,14 @@ public class RegionGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates this file needs to be saved, will actually get saved later by a task
|
||||
* Indicates this file needs to be saved, will actually get saved later by a task.
|
||||
*/
|
||||
public void saveRequired() {
|
||||
plugin.getFileManager().saveGroupsIsRequired();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save the groups to disk now, normally saveRequired() is preferred because of performance
|
||||
* Save the groups to disk now, normally saveRequired() is preferred because of performance.
|
||||
*/
|
||||
public void saveNow() {
|
||||
plugin.getFileManager().saveGroupsNow();
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 161 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user