Compare commits

...
150 Commits
Author SHA1 Message Date
md5sha256 88f55bb6a9 Release 2.7.16 2023-12-06 20:13:28 +08:00
md5sha256 4ba8326314 Update dependencies and minor buildscript changes 2023-12-06 20:01:08 +08:00
md5sha256 de81d92da0 Update the SDK before installing 2023-12-06 19:50:50 +08:00
md5sha256 f636a98314 Use temurin jdk in jitpack.yml 2023-12-06 19:45:08 +08:00
md5sha256 e4df5a8cc9 Update gradle wrapper to 8.5 2023-12-06 19:33:54 +08:00
Andrew Wong 56818bebdb Add transfer feature
Adds /as transfer
2023-11-24 21:50:07 +11:00
Andrew Wong 7e1d7168f1 Refactor transfer to transfer both buyers and renters. Update lang files and fix data keys in GeneralRegion 2023-11-24 21:47:40 +11:00
Andrew Wong ff1ea3ae51 Add default config for transfers 2023-11-24 21:47:38 +11:00
Andrew Wong c9dc8dd840 Add SetTransferCommand 2023-11-24 21:47:36 +11:00
Andrew Wong c0794daeeb Actually respect transfers being disabled 2023-11-24 21:47:34 +11:00
Andrew Wong d40b9c660b Fix transfer missing region arg replacement and incorrect ownership checks in TransferCommand 2023-11-24 21:47:32 +11:00
Andrew Wong f7b010b3f3 Fix lang issue with region not being replaced, fix landlord/owner not being changed 2023-11-24 21:47:30 +11:00
Andrew Wong a06d9271c4 Make sure tab complete list is mutable in transfer command 2023-11-24 21:47:27 +11:00
Andrew Wong dd343aa587 Add messages for when regions are transferred 2023-11-24 21:47:25 +11:00
Andrew Wong e09d4ebd83 Fix lang and incorrect argument access 2023-11-24 21:47:23 +11:00
Andrew Wong 5f435941e4 Add transfer region command 2023-11-24 21:47:19 +11:00
Andrew Wong 86316cdd5b Prepare for snapshot 2.7.16 2023-11-24 21:43:33 +11:00
Andrew Wong 61828d3cfd Release 2.7.15 2023-11-24 21:38:48 +11:00
Andrew Wong 54241d5ce3 Replace the warning of null owner on shutdown with null checks of the owner uuid 2023-11-15 13:06:22 +11:00
Andrew Wong d048665530 Cache the landlord instead of parsing it twice in GeneralRegion#isLandLord 2023-11-15 13:01:34 +11:00
Andrew Wong 23de68431c Replace Random instantiations with ThreadLocalRandom in FindCommand 2023-11-15 12:40:17 +11:00
Andrew Wong 95b4543f19 Fix null pointer when comparing null pre release types in VersionData 2023-11-14 03:46:28 +11:00
Andrew Wong d058bb7271 Refactor platform adapters to legacy (1.17.1) and modern (1.18+). Add semver parsing utilities. Fix bug with github updater treating snapshot versions as newer 2023-11-13 22:30:34 +11:00
Andrew Wong 63d26be369 2.7.15-SNAPSHOT 2023-11-13 21:06:58 +11:00
Andrew Wong 1020388aae Release 2.7.14 2023-11-12 18:04:01 +11:00
Andrew Wong e56107ffd6 Fix signs not being deleted from the global sign cache in memory 2023-11-12 17:59:34 +11:00
Andrew Wong 06fceb4643 Drop support for 1.20 and 1.20.1 2023-11-12 15:50:51 +11:00
Andrew Wong e2077c3b32 Fix region signs losing their interactivity after restart. Resolves #20 2023-11-12 15:40:03 +11:00
Andrew Wong fcb64c2ddb Merge pull request #22 from o0sh4d0w0o/ResoldRegionEvent-resellprice-fix
Fixed getResellPrice unsetted when ResoldRegionEvent is notified
2023-10-04 21:35:03 +11:00
o0sh4d0w0o cc51109720 Fixed getResellPrice unsetted when ResoldRegionEvent is notified 2023-10-01 16:03:07 +02:00
Andrew Wong 0b48f4dd2e Fix not including 1.20.2 adapter 2023-09-25 11:37:12 +10:00
Andrew Wong 4d7f00b0ce Add support for 1.20.2 2023-09-25 11:33:02 +10:00
Andrew Wong b27ea83982 Include 1.18-1.20 adapters for jitpack 2023-09-03 08:47:21 +10:00
Andrew Wong 66da717a77 Fix relocations 2023-09-03 08:47:19 +10:00
Andrew Wong 7f779d2df8 Bump version to 2.7.14-SNAPSHOT 2023-09-03 08:47:16 +10:00
Andrew Wong ed3bd01f2a Fix bad release url
Fixes #19
2023-09-03 07:22:58 +10:00
Andrew Wong ef03501d1c 2.7.13 release 2023-08-30 22:09:28 +10:00
Andrew Wong feb35cfd37 User api for BlockBehaviourImpl 1.18 onwards 2023-08-30 22:08:50 +10:00
Andrew Wong b6a8dcc24c Fix module desc for paper 1.20 2023-08-30 20:23:05 +10:00
Andrew Wong 5619612a6e Update gradle wrapper 2023-08-28 23:10:54 +10:00
Andrew Wong 26ac52cc0a Include plugin adapters in jitpack build 2023-08-28 22:46:14 +10:00
Andrew Wong 5f6bd55afe Don't include nms impls if on jitpack 2023-08-28 22:34:28 +10:00
Andrew Wong aba2e12c5d Don't include nms impls if on jitpack 2023-08-28 22:26:28 +10:00
Andrew Wong 2906de11de Fix merge conflicts 2023-08-28 22:17:42 +10:00
Andrew Wong 436672f85b Don't shadowJar and don't include nms providers if building on jitpack 2023-08-28 22:12:09 +10:00
Andrew Wong 5ba8ed7ad8 Add spotbugs 2023-08-28 20:57:17 +10:00
Andrew Wong 00d97f1beb Update dependencies 2023-08-28 20:36:52 +10:00
Andrew Wong f530fa40af Fix signs not being saved on server stop 2023-08-28 20:14:12 +10:00
Andrew Wong a804df2257 Add jitpack logo 2023-08-09 14:08:12 +10:00
Andrew Wong c96e0b464e More jitpack tests 2023-08-09 13:58:44 +10:00
Andrew Wong 13e52aa4f1 More jitpack tests 2023-08-09 13:55:52 +10:00
Andrew Wong 9aeb531d16 More jitpack tests 2023-08-09 13:52:23 +10:00
Andrew Wong 44f83473d1 Add jitpack.yml 2023-08-09 13:46:05 +10:00
Andrew Wong d7260998f5 Update Guice to 7.0.0 and use JakartaEE annotations 2023-06-12 00:59:16 +10:00
Andrew Wong 638382eacf Snapshot 2.7.13 2023-06-12 00:58:34 +10:00
Andrew Wong e18fe99161 Release 2.7.12 2023-06-12 00:40:46 +10:00
Andrew Wong bdc9e32c13 Add support for 1.20 2023-06-12 00:40:08 +10:00
Andrew Wong 9a46d5ae3b Bump version to 2.7.12-SNAPSHOT 2023-03-29 16:14:26 +11:00
Andrew Wong 6795fc43d9 Release 2.7.11 2023-03-29 16:13:54 +11:00
Andrew Wong dd9bd2c434 Drop support for 1.19.3 and add support for 1.19.4 2023-03-29 16:13:23 +11:00
Andrew Wong 9438166180 Prepare for development 2.7.11 2023-02-27 21:58:41 +11:00
Andrew Wong 9e06b9f268 Release 2.7.10 2023-02-27 21:58:14 +11:00
Andrew Wong 4562bf23f6 Update libs 2023-02-27 21:57:49 +11:00
Andrew Wong 24edb01754 Refactor GeneralRegion#getOwner, #isOwner and #setOwner 2023-02-27 21:46:59 +11:00
Andrew Wong 2739bf6ad4 Fix javadocs for IFileManager 2023-02-27 21:41:28 +11:00
Andrew Wong 2ce84186ab Use Server#getOfflinePlayer in PlayerOfflinePlayerHelper 2023-02-27 21:39:48 +11:00
Andrew Wong 279fa001ea Only support 1.19.3 2023-02-27 11:56:41 +11:00
Andrew Wong b56d5320a6 Add support for 1.19.3 2022-12-15 16:25:06 +08:00
Andrew Wong 30665908b9 Bump to 2.7.10-SNAPSHOT 2022-12-09 16:53:03 +08:00
Andrew Wong 0fd384833a Bump version to 2.7.9 release 2022-12-09 16:45:57 +08:00
Andrew Wong 09634de4bf Fix BukkitSchedulerExecutor not having an injectable ctor 2022-12-07 12:13:34 +08:00
Andrew Wong 7fafee82a7 Minor cleanup 2022-12-07 11:59:37 +08:00
Andrew Wong 2899b2978c Rewrite SetownerCommand 2022-12-07 11:56:50 +08:00
Andrew Wong 7afcba79c9 Rewrite SetlandlordCommand 2022-12-07 11:53:44 +08:00
Andrew Wong 72084b38f8 Use OfflinePlayerHelper in MeCommand 2022-12-07 11:49:01 +08:00
Andrew Wong 6a291feedd Rewrite DelFriendCommand 2022-12-07 11:45:16 +08:00
Andrew Wong b85566882c Rewrite AddfriendCommand 2022-12-07 11:39:09 +08:00
Andrew Wong c14407e14b Add PaperPlatform 2022-12-07 01:23:12 +08:00
Andrew Wong ae9bd60d1b Fix typo 2022-09-14 21:25:04 +08:00
Andrew Wong c689c2fae0 Fix dependency versions for WG and WE, and add a section for FAWE 2022-09-14 21:24:48 +08:00
Andrew Wong 728cfb6dfa Add a compiling.md 2022-09-14 21:16:03 +08:00
Andrew Wong 3abb6c06e4 Update readme 2022-09-14 20:56:00 +08:00
Andrew Wong 51c11738af Prepare for snapshot development 2022-09-12 22:39:45 +08:00
Andrew Wong 172b5a99f1 Bump version to release 2022-09-12 22:21:28 +08:00
Andrew Wong 4c5d025e54 Add config option to toggle whether entities are forcefully cleared 2022-09-12 22:20:55 +08:00
Andrew Wong e93a2d04de Forcefully remove entities from FAWE/WE regions before schematic pasting 2022-09-12 22:12:18 +08:00
Andrew Wong af5980d555 Change the messages for update checking and report file manager loading failures 2022-09-12 17:58:09 +08:00
Andrew Wong 3f7249f4a1 Merge pull request #13 from cleonyc/dev/bleeding
Allow unrented event to use placeholders
2022-09-12 17:39:56 +08:00
Andrew Wong 73c6fc858e Update the logging methods to invoke conditionally 2022-09-12 17:37:47 +08:00
Andrew Wong 360c3e7e21 Use Suppliers when logging in the plugin adapters 2022-09-12 17:35:55 +08:00
Andrew Wong 73d0115b78 Actually fix the FAWE and WE handlers when pasting 2022-09-12 17:25:27 +08:00
Andrew Wong baf7eaabf1 Bump versions of WE and FAWE in the libs.toml 2022-09-11 00:50:36 +08:00
Andrew Wong ca8c0487a8 Fix origin setting so that the blocks paste properly 2022-09-11 00:44:47 +08:00
Andrew Wong 24156a03c4 Rewrite region saving and restoring in the adapters 2022-09-10 23:14:28 +08:00
Andrew Wong ec677766d2 Attempt to prevent duplicate signs from loading 2022-09-10 19:27:03 +08:00
Andrew Wong ef6c8fbf9d Only remove leashes, paintings and item frames 2022-09-10 17:54:48 +08:00
Andrew Wong 4f52fe9e6e Forcefully remvoe Entities in the region before pasting 2022-09-10 17:43:07 +08:00
Andrew Wong 3ebe5a6fa9 Use the WG converter to convert WG regions to WE ones 2022-09-10 17:02:29 +08:00
Andrew Wong 3cebe5d2c7 Fix NPE with sign deletion after worlededit operations 2022-09-10 14:59:35 +08:00
Andrew Wong c76415c4f3 Fix NPE when tabbing region restore 2022-09-10 12:47:45 +08:00
Andrew Wong b7bc02aef3 Compile against 1.19.2 and update the gradle wrapper 2022-09-07 15:31:33 +08:00
Cleo d75094e191 Remove unrenting section in eventCommandProfile 2022-07-07 13:51:02 -04:00
Cleo 4045914b48 Fix placeholders in unrented command event [#11] 2022-07-07 13:50:04 -04:00
Andrew Wong 1fac002ee0 Remove the Bukkit113 module and update the versioning url 2022-06-20 19:57:22 +08:00
Andrew Wong 64301e74e0 Bump version 2022-06-20 19:27:28 +08:00
Andrew Wong 5a5a7fc5ef Bump version 2022-06-20 19:25:42 +08:00
Andrew Wong b928caf0c2 Bump worldedit 2022-06-20 19:19:49 +08:00
Andrew Wong 111f629787 Update dependencies and add adapter for 1.19 2022-06-11 00:59:19 +08:00
Andrew Wong 718474ca95 Update gradle wrapper 2022-06-10 23:37:12 +08:00
Andrew Wong 93b9df3e54 Update gradle wrapper to 7.4.1 2022-03-24 18:48:03 +08:00
Andrew Wong bad983a0b8 Update worldedit and fawe adapters 2022-03-24 18:47:02 +08:00
Andrew Wong e2c8b06b68 Bump dependency versions 2022-03-24 16:30:02 +08:00
Andrew Wong 7249e39c02 bump version 2022-03-24 16:27:49 +08:00
Andrew Wong 9d9a58a170 bump to 2.7.6 2022-03-24 16:24:56 +08:00
Andrew Wong e64e884c2a Updates to the fawe module 2022-03-05 00:00:34 +08:00
Andrew Wong 6ad4ff9deb Shade in the provider for 1.18.1 2022-03-05 00:00:23 +08:00
Andrew Wong eec9806492 Add back support for 1.18.1 2022-03-04 23:08:43 +08:00
Andrew Wong 43b2ae8278 Fix bad website in plugin.yml 2022-03-04 22:54:40 +08:00
Andrew Wong 6d5a92e389 1.18.2 2022-03-04 22:48:39 +08:00
Andrew Wong 7d7a62ffa0 Bump gradle wrapper to 7.4 2022-03-03 17:41:52 +08:00
md5sha256 44456d87b6 Fix the sign error file extension 2022-01-25 05:49:47 +08:00
md5sha256 d92c710b27 bump version to snapshot 2022-01-25 05:49:35 +08:00
md5sha256 3dceaf98cd Bump version to 2.7.5 2022-01-25 05:35:08 +08:00
md5sha256 33c29a3756 Fix the fawe integration and do operations async when possible 2022-01-25 05:34:34 +08:00
md5sha256 771734360f add workflow 2022-01-16 23:24:28 +08:00
md5sha256 539e908d32 Initial work on fixing the deadlock in the fawe module 2022-01-16 21:45:11 +08:00
md5sha256 088471aa3c more project restructuring 2022-01-16 21:28:28 +08:00
md5sha256 5a95c95670 Fix gitignore and restructure project 2022-01-16 20:58:44 +08:00
md5sha256 5a5d627d51 Fix publishing 2022-01-16 15:26:54 +08:00
md5sha256 9b5434a4b2 Add type safe project acessors and version catalog 2022-01-16 14:40:19 +08:00
md5sha256 e13717950b Kotlin dsl 2022-01-16 12:05:39 +08:00
md5sha256 03ed2803bd Bump version to 2.7.3 2022-01-15 07:38:40 +08:00
md5sha256 b3f1225934 Deprecate the FAWE WG handler and fix fawe version parsing 2022-01-15 07:36:43 +08:00
md5sha256 68651899b7 Update the fawe module 2022-01-10 22:59:03 +08:00
md5sha256 4a7a4ca4ee Fix reobf 2022-01-10 22:34:35 +08:00
md5sha256 0d272c8fe9 Publish nms provider poms 2021-12-05 23:07:05 +08:00
md5sha256 6b2c905939 Parallel builds 2021-12-05 22:57:17 +08:00
md5sha256 7ab782799b Fix maven publish tasks 2021-12-05 22:57:03 +08:00
md5sha256 bea82eae88 Fix maven publish tasks 2021-12-05 22:56:37 +08:00
md5sha256 4ac0e045bd Add maven publish task 2021-12-05 18:22:41 +08:00
md5sha256 e5061b218e Java 17 and 1.18 2021-12-01 17:59:17 +08:00
md5sha256 40fdfba47d Fix silly typo in the buildscript 2021-11-18 22:16:36 +08:00
md5sha256 e9260cede6 Bump gradle wrapper version to 7.3 2021-11-18 22:14:56 +08:00
md5sha256 bb297c9ff1 Bump version 2021-11-16 15:28:14 +08:00
Andrew Wong 666742ad56 Merge pull request #2 from md5sha256/feature/purge 2021-11-16 15:25:54 +08:00
md5sha256 36eb8c3a5e Fix imports 2021-11-16 15:25:01 +08:00
Olzie-12 06a9f7b28e file management 2021-11-14 14:41:41 +00:00
md5sha256 e101780420 Fix compat for file manager 2021-11-11 13:31:09 +08:00
md5sha256 6abe99e807 Log sign warnings to the sign error logger 2021-11-09 19:06:02 +08:00
md5sha256 a1d18521ee Introduce interface for FileManager 2021-10-11 00:00:57 +08:00
134 changed files with 3517 additions and 2263 deletions

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
name: Java CI with Gradle
on: [ push, pull_request ]
jobs:
build:
# Only run on PRs if the source branch is on someone else's repo
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
strategy:
matrix:
os: ["ubuntu-latest", "windows-latest"]
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1.0.4
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'zulu'
cache: 'gradle'
- name: Build with Gradle
run: ./gradlew clean build
+20 -37
View File
@@ -1,13 +1,11 @@
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,intellij,maven,gradle
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,intellij,maven,gradle
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,intellij+all,gradle,maven
### Intellij ###
### Intellij+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/**
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
@@ -68,6 +66,9 @@ atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
@@ -80,35 +81,21 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
### Intellij+all Patch ###
# Ignores the whole .idea folder and all .iml files
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
.idea/*
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
.idea/sonarlint
### macOS ###
# General
@@ -152,7 +139,6 @@ buildNumber.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
### Maven Patch ###
# Eclipse m2e generated files
# Eclipse Core
.project
@@ -188,6 +174,7 @@ $RECYCLE.BIN/
### Gradle ###
.gradle
build/
build-cache/
# Ignore Gradle GUI config
gradle-app.setting
@@ -204,8 +191,4 @@ gradle-app.setting
### Gradle Patch ###
**/build/
# Eclipse Gradle plugin generated files
# Eclipse Core
# JDT-specific (Eclipse Java Development Tools)
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij,maven,gradle
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>
-76
View File
@@ -1,76 +0,0 @@
import org.apache.tools.ant.filters.ReplaceTokens
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.0'
}
version = "2.7.0-SNAPSHOT"
dependencies {
implementation 'com.github.NLthijs48:InteractiveMessenger:e7749258ca'
implementation 'com.github.NLthijs48:BukkitDo:819d51ec2b'
implementation 'io.papermc:paperlib:1.0.6'
implementation 'io.github.baked-libs:dough-data:1.0.3'
implementation ('com.google.inject:guice:5.0.1') {
exclude group: 'com.google.guava'
}
implementation ('com.google.inject.extensions:guice-assistedinject:5.0.1') {
exclude group: 'com.google.guava'
}
implementation project(':areashop-interface')
implementation project(':areashop-bukkit-1_13')
implementation project(':areashop-nms')
implementation project(':areashop-nms-1-17')
implementation project(':areashop-worldedit-7')
implementation project(':areashop-worldguard-7')
implementation project(':areashop-fastasyncworldedit')
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly ('com.sk89q.worldedit:worldedit-bukkit:7.2.5') {
exclude group: 'com.google.guava'
}
compileOnly ('com.sk89q.worldguard:worldguard-bukkit:7.0.5') {
exclude group: 'com.google.guava'
}
compileOnly ('com.github.MilkBowl:VaultAPI:1.7')
}
processResources {
from (sourceSets.main.resources) {
filter ReplaceTokens, tokens: [version: project.version]
duplicatesStrategy(DuplicatesStrategy.INCLUDE)
}
}
assemble {
dependsOn(shadowJar)
}
jar {
archiveClassifier.set('original')
}
compileJava {
javaToolchains.compilerFor {
JavaLanguageVersion.of(16)
}
}
shadowJar {
archiveClassifier.set('')
setArchivesBaseName('AreaShop')
String base = "me.wiefferink.areashop.libraries"
relocate('me.wiefferink.interactivemessenger', "${base}.interactivemessenger")
relocate('me.wiefferink.bukkitdo', "${base}.bukkitdo")
relocate('io.papermc.lib', "${base}.paperlib")
relocate('io.github.bakedlibs.dough', "${base}.dough")
relocate("com.google.inject", "${base}.inject")
relocate("org.aopalliance", "${base}.aopalliance")
relocate("javax.inject", "${base}.javax.inject")
include {
include("com.google.inject")
minimize()
}
}
description = 'AreaShop'
+105
View File
@@ -0,0 +1,105 @@
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
}
description = "AreaShop"
dependencies {
// Platform
compileOnlyApi(libs.spigot)
compileOnlyApi(libs.worldeditCore) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldeditBukkit) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldguardCore) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldguardBukkit) {
exclude("com.google.guava", "guava")
}
compileOnlyApi("com.github.MilkBowl:VaultAPI:1.7") {
exclude("com.google.guava", "guava")
}
// 3rd party libraries
implementation("io.papermc:paperlib:1.0.8")
implementation("com.github.NLthijs48:InteractiveMessenger:e7749258ca")
implementation("com.github.NLthijs48:BukkitDo:819d51ec2b")
implementation("io.github.baked-libs:dough-data:1.2.0")
implementation("com.google.inject:guice:7.0.0") {
exclude("com.google.guava", "guava")
}
implementation("com.google.inject.extensions:guice-assistedinject:7.0.0") {
exclude("com.google.guava", "guava")
}
// Project submodules
implementation(projects.areashopInterface)
implementation(projects.areashopNms)
implementation(projects.adapters.platform.platformInterface)
implementation(projects.adapters.platform.paper)
runtimeOnly(projects.adapters.plugins.worldedit)
runtimeOnly(projects.adapters.plugins.worldguard)
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
// Adapters
if (!providers.environmentVariable("JITPACK").isPresent) {
runtimeOnly(project(":adapters:platform:bukkit-1-17", "reobf"))
}
runtimeOnly(projects.adapters.platform.bukkitModern)
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.57.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.1")
}
repositories {
mavenCentral()
}
tasks {
processResources {
filesMatching("plugin.yml") {
expand("version" to project.version)
}
}
assemble {
if (!providers.systemProperty("JITPACK").isPresent) {
dependsOn(shadowJar)
}
}
jar {
archiveClassifier.set("original")
}
java {
withSourcesJar()
}
val javaComponent = project.components["java"] as AdhocComponentWithVariants
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
skip()
}
shadowJar {
archiveClassifier.set("")
base {
archiveBaseName.set("AreaShop")
}
val base = "me.wiefferink.areashop.libraries"
relocate("me.wiefferink.interactivemessenger", "${base}.interactivemessenger")
relocate("me.wiefferink.bukkitdo", "${base}.bukkitdo")
relocate("io.papermc.lib", "${base}.paperlib")
relocate("io.github.bakedlibs.dough", "${base}.dough")
relocate("com.google.inject", "${base}.inject")
relocate("com.google.errorprone", "${base}.errorprone")
relocate("org.aopalliance", "${base}.aopalliance")
relocate("javax.annotation", "${base}.javax.annotation")
relocate("jakarta.inject", "${base}.jakarta.inject")
}
}
@@ -6,14 +6,17 @@ import com.google.inject.Stage;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.managers.RegionManager;
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import me.wiefferink.areashop.adapters.platform.paper.PaperPlatform;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.listeners.PlayerLoginLogoutListener;
import me.wiefferink.areashop.managers.CommandManager;
import me.wiefferink.areashop.managers.FeatureManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.Manager;
import me.wiefferink.areashop.managers.SignErrorLogger;
@@ -21,10 +24,15 @@ import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.modules.AreaShopModule;
import me.wiefferink.areashop.modules.BukkitModule;
import me.wiefferink.areashop.modules.DependencyModule;
import me.wiefferink.areashop.nms.NMS;
import me.wiefferink.areashop.modules.PlatformModule;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.tools.GithubUpdateCheck;
import me.wiefferink.areashop.tools.SimpleMessageBridge;
import me.wiefferink.areashop.tools.SpigotPlatform;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.areashop.tools.version.Version;
import me.wiefferink.areashop.tools.version.VersionData;
import me.wiefferink.areashop.tools.version.VersionUtil;
import me.wiefferink.bukkitdo.Do;
import me.wiefferink.interactivemessenger.source.LanguageManager;
import net.milkbowl.vault.economy.Economy;
@@ -49,8 +57,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.function.Supplier;
/**
* Main class for the AreaShop plugin.
@@ -66,10 +73,9 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
private WorldGuardInterface worldGuardInterface = null;
private WorldEditPlugin worldEdit = null;
private WorldEditInterface worldEditInterface = null;
private NMS nms;
private BukkitInterface bukkitInterface = null;
private PlatformAdapter platformAdapter;
private MessageBridge messageBridge;
private FileManager fileManager = null;
private IFileManager fileManager = null;
private LanguageManager languageManager = null;
private CommandManager commandManager = null;
private SignLinkerManager signLinkerManager = null;
@@ -90,7 +96,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
public static final String defaultFile = "default.yml";
public static final String configFile = "config.yml";
public static final String configFileHidden = "hiddenConfig.yml";
public static final String signLogFile = "sign-errors.yml";
public static final String signLogFile = "sign-errors.log";
public static final String versionFile = "versions";
// Euro tag for in the config
@@ -165,210 +171,127 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
AreaShop.instance = this;
Do.init(this);
managers = new HashSet<>();
boolean error = false;
messageBridge = new SimpleMessageBridge();
signErrorLogger = new SignErrorLogger(new File(getDataFolder(), signLogFile));
// Setup NMS Impl
String rawServerVersion = Bukkit.getServer().getClass().getPackageName();
String[] split = rawServerVersion.split("\\.");
String serverVersion = split[3];
try {
Class<?> nmsImpl = Class.forName("me.wiefferink.areashop.nms." + serverVersion + ".NMSImpl");
this.nms = nmsImpl.asSubclass(NMS.class).getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
getLogger().severe("Failed to initialize NMS implementation!");
getServer().getPluginManager().disablePlugin(this);
Version currentServerVersion = VersionUtil.parseMinecraftVersion(Bukkit.getBukkitVersion());
if (currentServerVersion.versionData().isOlderThan(VersionUtil.MC_1_17_1)) {
error("Unsupported minecraft version: " + currentServerVersion + "! Minimum is 1.17.1");
shutdownOnError();
return;
}
if (currentServerVersion.versionData().equals(VersionUtil.MC_1_17_1)) {
try {
Class<?> adapterImpl = Class.forName("me.wiefferink.areashop.adapters.platform.legacy.LegacyPlatformAdapter");
this.platformAdapter = adapterImpl.asSubclass(PlatformAdapter.class).getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
error("Failed to initialize legacy PlatformAdapter implementation!");
shutdownOnError();
return;
}
} else {
try {
Class<?> adapterImpl = Class.forName("me.wiefferink.areashop.adapters.platform.modern.ModernPlatformAdapter");
this.platformAdapter = adapterImpl.asSubclass(PlatformAdapter.class).getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
error("Failed to initialize modern PlatformAdapter implementation!");
shutdownOnError();
return;
}
}
final MinecraftPlatform platform;
if (PaperLib.isPaper()) {
platform = new PaperPlatform(this);
info("Detected Paper; using the PaperPlatform impl");
} else {
platform = new SpigotPlatform(this);
info("Detected Spigot; using the SpigotPlatform impl");
}
final PlatformModule platformModule = new PlatformModule(platform, this.platformAdapter);
// Check if Vault is present
if(getServer().getPluginManager().getPlugin("Vault") == null) {
error("Vault plugin is not present or has not loaded correctly");
shutdownOnError();
return;
}
// Find WorldEdit integration version to load
String weVersion = null;
String rawWeVersion = null;
String weBeta = null;
String weHandlerVersion;
Plugin plugin = getServer().getPluginManager().getPlugin("WorldEdit");
if(!(plugin instanceof WorldEditPlugin) || !plugin.isEnabled()) {
error("WorldEdit plugin is not present or has not loaded correctly");
error = true;
return;
} else {
worldEdit = (WorldEditPlugin)plugin;
rawWeVersion = worldEdit.getDescription().getVersion();
// Find beta version
Pattern pattern = Pattern.compile("beta-?\\d+");
Matcher matcher = pattern.matcher(rawWeVersion);
if (matcher.find()) {
weBeta = matcher.group();
}
// Get correct WorldEditInterface (handles things that changed version to version)
if(worldEdit.getDescription().getVersion().startsWith("7.")) {
weVersion = "7";
this.worldEdit = (WorldEditPlugin) plugin;
Plugin fawePlugin = getServer().getPluginManager().getPlugin("FastAsyncWorldEdit");
if (fawePlugin != null && fawePlugin.isEnabled()) {
weHandlerVersion = "FastAsyncWorldEditHandler";
info("Detected FastAsyncWorldEdit, using the fawe handler");
} else {
throw new IllegalStateException("Unknown WE Version: " + worldEdit.getDescription().getVersion());
weHandlerVersion = "WorldEditHandler";
}
weVersion = "WorldEditHandler" + weVersion;
}
// Find WorldGuard integration version to load
String wgVersion = null;
String rawWgVersion = null;
int major = 0;
int minor = 0;
int fixes = 0;
Integer build = null;
plugin = getServer().getPluginManager().getPlugin("WorldGuard");
if(!(plugin instanceof WorldGuardPlugin) || !plugin.isEnabled()) {
error("WorldGuard plugin is not present or has not loaded correctly");
error = true;
shutdownOnError();
return;
} else {
worldGuard = (WorldGuardPlugin)plugin;
// Get correct WorldGuardInterface (handles things that changed version to version)
try {
rawWgVersion = worldGuard.getDescription().getVersion();
if(rawWgVersion.contains("-SNAPSHOT;")) {
String buildNumber = rawWgVersion.substring(rawWgVersion.indexOf("-SNAPSHOT;") + 10);
if(buildNumber.contains("-")) {
buildNumber = buildNumber.substring(0, buildNumber.indexOf('-'));
if (Utils.isNumeric(buildNumber)) {
build = Integer.parseInt(buildNumber);
} else {
warn("Could not correctly parse the build of WorldGuard, raw version: " + rawWgVersion + ", buildNumber: " + buildNumber);
}
}
}
// Clear stuff from the version string that is not a number
String[] versionParts = rawWgVersion.split("\\.");
for(int i = 0; i < versionParts.length; i++) {
Pattern pattern = Pattern.compile("^\\d+");
Matcher matcher = pattern.matcher(versionParts[i]);
if(matcher.find()) {
versionParts[i] = matcher.group();
}
}
// Find major, minor and fix numbers
try {
if(versionParts.length > 0) {
major = Integer.parseInt(versionParts[0]);
}
if(versionParts.length > 1) {
minor = Integer.parseInt(versionParts[1]);
}
if(versionParts.length > 2) {
fixes = Integer.parseInt(versionParts[2]);
}
} catch(NumberFormatException e) {
warn("Something went wrong while parsing WorldGuard version number: " + rawWgVersion);
}
// Determine correct implementation to use
if(rawWgVersion.startsWith("7.")) {
wgVersion = "7";
}
} catch(Exception e) { // If version detection fails, at least try to load the latest version
warn("Parsing the WorldGuard version failed, assuming version 7:", rawWgVersion);
wgVersion = "7";
}
wgVersion = "WorldGuardHandler" + wgVersion;
this.worldGuard = (WorldGuardPlugin) plugin;
}
DependencyModule dependencyModule = new DependencyModule(worldEdit, worldGuard, getEconomy(), getPermissionProvider());
// Check if FastAsyncWorldEdit is installed
boolean fawe;
try {
Class.forName("com.fastasyncworldedit.core.FaweAPI" );
fawe = true;
} catch (ClassNotFoundException ignore) {
fawe = false;
}
if (fawe) {
weVersion = "FastAsyncWorldEditHandler";
}
DependencyModule dependencyModule = new DependencyModule(this.worldEdit, this.worldGuard, getEconomy(), getPermissionProvider());
// Load WorldEdit
try {
Class<?> clazz = Class.forName("me.wiefferink.areashop.handlers." + weVersion);
// Check if we have a NMSHandler class at that location.
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins." + weHandlerVersion);
if(WorldEditInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldEditInterface
worldEditInterface = (WorldEditInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
}
} catch(Exception e) {
error("Could not load the handler for WorldEdit (tried to load " + weVersion + "), report this problem to the author: " + ExceptionUtils.getStackTrace(e));
error = true;
weVersion = null;
error("Could not load the handler for WorldEdit (tried to load " + weHandlerVersion + "), report this problem to the author: " + ExceptionUtils.getStackTrace(e));
shutdownOnError();
return;
}
// Load WorldGuard
try {
Class<?> clazz = Class.forName("me.wiefferink.areashop.handlers." + wgVersion);
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins.WorldGuardHandler");
// Check if we have a NMSHandler class at that location.
if(WorldGuardInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldGuardInterface
worldGuardInterface = (WorldGuardInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
}
} catch(Exception e) {
error("Could not load the handler for WorldGuard (tried to load " + wgVersion + "), report this problem to the author:" + ExceptionUtils.getStackTrace(e));
error = true;
wgVersion = null;
error("Could not load the handler for WorldGuard, report this problem to the author:" + ExceptionUtils.getStackTrace(e));
shutdownOnError();
return;
}
// Load Bukkit implementation
String bukkitHandler;
try {
Class.forName("org.bukkit.block.data.type.WallSign");
bukkitHandler = "1_13";
} catch (ClassNotFoundException e) {
bukkitHandler = "1_12";
}
try {
Class<?> clazz = Class.forName("me.wiefferink.areashop.handlers.BukkitHandler" + bukkitHandler);
bukkitInterface = (BukkitInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this);
} catch (Exception e) {
error("Could not load the Bukkit handler (used for sign updates), tried to load:", bukkitHandler + ", report this problem to the author:", ExceptionUtils.getStackTrace(e));
error = true;
bukkitHandler = null;
}
// Check if Vault is present
if(getServer().getPluginManager().getPlugin("Vault") == null) {
error("Vault plugin is not present or has not loaded correctly");
error = true;
}
AreaShopModule asModule = new AreaShopModule(this, messageBridge, nms, bukkitInterface, worldEditInterface, worldGuardInterface, signErrorLogger, dependencyModule);
AreaShopModule asModule = new AreaShopModule(this, messageBridge,
platformAdapter, worldEditInterface, worldGuardInterface, signErrorLogger, platformModule, dependencyModule);
injector = Guice.createInjector(Stage.PRODUCTION, new BukkitModule(getServer()), asModule);
// Load all data from files and check versions
fileManager = injector.getInstance(FileManager.class);
managers.add(fileManager);
fileManager = injector.getInstance(IFileManager.class);
managers.add((FileManager) fileManager);
boolean loadFilesResult = fileManager.loadFiles(false);
error = error || !loadFilesResult;
// Print loaded version of WG and WE in debug
if(wgVersion != null) {
AreaShop.debug("Loaded ", wgVersion, "(raw version:" + rawWgVersion + ", major:" + major + ", minor:" + minor + ", fixes:" + fixes + ", build:" + build + ", fawe:" + fawe + ")");
}
if(weVersion != null) {
AreaShop.debug("Loaded ", weVersion, "(raw version:" + rawWeVersion + ", beta:" + weBeta + ")");
}
if(bukkitHandler != null) {
AreaShop.debug("Loaded BukkitHandler", bukkitHandler);
if (!loadFilesResult) {
shutdownOnError();
return;
}
setupLanguageManager();
if(error) {
error("The plugin has not started, fix the errors listed above");
return;
}
featureManager = injector.getInstance(FeatureManager.class);
featureManager.initializeFeatures(injector);
managers.add(featureManager);
signManager = new SignManager();
signManager = injector.getInstance(SignManager.class);
managers.add(signManager);
// Register the event listeners
@@ -391,17 +314,20 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
if(getConfig().getBoolean("checkForUpdates")) {
githubUpdateCheck = new GithubUpdateCheck(
this,
"NLThijs48",
"md5sha256",
"AreaShop"
).withVersionComparator((latestVersion, currentVersion) ->
!cleanVersion(latestVersion).equals(cleanVersion(currentVersion))
).withVersionComparator((latestVersion, currentVersion) -> {
Version latest = Version.parse(cleanVersion(latestVersion));
Version current = Version.parse(cleanVersion(currentVersion));
return latest.versionData().isNewerThan(current.versionData());
}
).checkUpdate(result -> {
AreaShop.debug("Update check result:", result);
if(!result.hasUpdate()) {
return;
}
AreaShop.info("Update from AreaShop V" + cleanVersion(result.getCurrentVersion()) + " to AreaShop V" + cleanVersion(result.getLatestVersion()) + " available, get the latest version at https://www.spigotmc.org/resources/areashop.2991/");
AreaShop.info("Update from AreaShop V" + cleanVersion(result.getCurrentVersion()) + " to AreaShop V" + cleanVersion(result.getLatestVersion()) + " available, get the latest version at https://github.com/md5sha256/AreaShop/releases");
for(Player player : Utils.getOnlinePlayers()) {
notifyUpdate(player);
}
@@ -419,6 +345,11 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
}
}
private void shutdownOnError() {
error("The plugin has not started, fix the errors listed above");
getServer().getPluginManager().disablePlugin(this);
}
/**
* Cleanup a version number.
* @param version Version to clean
@@ -501,8 +432,8 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
this.chatprefix = chatprefix;
}
public NMS getNms() {
return nms;
public PlatformAdapter getPlatformAdapter() {
return platformAdapter;
}
public SignErrorLogger getSignErrorLogger() {
@@ -550,6 +481,11 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
return worldEdit;
}
@Override
public Plugin pluginInstance() {
return this;
}
/**
* Function to get WorldGuardInterface for version dependent things.
* @return WorldGuardInterface
@@ -566,14 +502,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
return languageManager;
}
/**
* Get the BukkitHandler, for sign interactions.
* @return BukkitHandler
*/
public BukkitInterface getBukkitHandler() {
return this.bukkitInterface;
}
/**
* Function to get the CommandManager.
* @return the CommandManager
@@ -660,7 +588,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
* Method to get the FileManager (loads/save regions and can be used to get regions).
* @return The fileManager
*/
public FileManager getFileManager() {
public IFileManager getFileManager() {
return fileManager;
}
@@ -800,12 +728,19 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
AreaShop.debug(StringUtils.join(message, " "));
}
@Override
public void debugI(Supplier<String> message) {
if (debug) {
info("Debug: " + message.get());
}
}
/**
* Print an information message to the console.
* @param message The message to print
*/
public static void info(Object... message) {
AreaShop.getInstance().getLogger().info(StringUtils.join(message, " "));
AreaShop.getInstance().getLogger().info(() -> StringUtils.join(message, " "));
}
/**
@@ -813,7 +748,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
* @param message The message to print
*/
public static void warn(Object... message) {
AreaShop.getInstance().getLogger().warning(StringUtils.join(message, " "));
AreaShop.getInstance().getLogger().warning(() -> StringUtils.join(message, " "));
}
/**
@@ -821,7 +756,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
* @param message The message to print
*/
public static void error(Object... message) {
AreaShop.getInstance().getLogger().severe(StringUtils.join(message, " "));
AreaShop.getInstance().getLogger().severe(() -> StringUtils.join(message, " "));
}
/**
@@ -1,6 +1,8 @@
package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
@@ -11,7 +13,7 @@ import me.wiefferink.areashop.events.notify.RentedRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
@@ -24,8 +26,6 @@ import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -164,14 +164,14 @@ public class AddCommand extends CommandAreaShop {
} else {
type = "buy";
}
FileManager.AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, world, isRent ? GeneralRegion.RegionType.RENT : GeneralRegion.RegionType.BUY);
if(result == FileManager.AddResult.ALREADYADDED) {
IFileManager.AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, world, isRent ? GeneralRegion.RegionType.RENT : GeneralRegion.RegionType.BUY);
if(result == IFileManager.AddResult.ALREADYADDED) {
regionsAlready.add(plugin.getFileManager().getRegion(regionName));
} else if(result == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
} else if(result == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
regionsAlreadyOtherWorld.add(plugin.getFileManager().getRegion(regionName));
} else if(result == FileManager.AddResult.BLACKLISTED) {
} else if(result == IFileManager.AddResult.BLACKLISTED) {
namesBlacklisted.add(regionName);
} else if(result == FileManager.AddResult.NOPERMISSION) {
} else if(result == IFileManager.AddResult.NOPERMISSION) {
namesNoPermission.add(regionName);
} else {
// Check if the player should be landlord
@@ -321,8 +321,7 @@ public class AddCommand extends CommandAreaShop {
result.add("buy");
}
} else if(toComplete == 3) {
if(sender instanceof Player) {
Player player = (Player)sender;
if(sender instanceof Player player) {
if(sender.hasPermission("areashop.createrent") || sender.hasPermission("areashop.createbuy")) {
for(ProtectedRegion region : plugin.getRegionManager(player.getWorld()).getRegions().values()) {
result.add(region.getId());
@@ -1,148 +1,142 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
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 org.bukkit.plugin.Plugin;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class AddfriendCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
@Inject
private Plugin plugin;
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop addfriend";
}
@Inject
private OfflinePlayerHelper offlinePlayerHelper;
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
return "help-addFriend";
}
return null;
}
@Inject
private BukkitSchedulerExecutor executor;
@SuppressWarnings("deprecation")
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
messageBridge.message(sender, "addfriend-noPermission");
return;
}
@Override
public String getCommandStart() {
return "areashop addfriend";
}
if(args.length < 2) {
messageBridge.message(sender, "addfriend-help");
return;
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
return "help-addFriend";
}
return null;
}
GeneralRegion region;
if(args.length <= 2) {
if(sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = fileManager.getRegion(args[2]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if(sender.hasPermission("areashop.addfriendall")) {
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
messageBridge.message(sender, "addfriend-noOwner", region);
return;
}
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
return;
}
if(region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
return;
}
if(region.isOwner(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
return;
}
if(region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "addfriend-successOther", friend.getName(), region);
}
} else {
if(sender.hasPermission("areashop.addfriend") && sender instanceof Player) {
if(region.isOwner((Player)sender)) {
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
return;
}
if(region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
return;
}
if(region.isOwner(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
return;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
messageBridge.message(sender, "addfriend-noPermission");
return;
}
if(region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "addfriend-success", friend.getName(), region);
}
} else {
messageBridge.message(sender, "addfriend-noPermissionOther", region);
}
} else {
messageBridge.message(sender, "addfriend-noPermission", region);
}
}
}
if (args.length < 2) {
messageBridge.message(sender, "addfriend-help");
return;
}
@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());
}
} else if(toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
GeneralRegion region;
if (args.length == 2) {
if (sender instanceof Player player) {
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = fileManager.getRegion(args[2]);
if (region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if (sender.hasPermission("areashop.addfriendall")) {
if ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
|| (region instanceof BuyRegion buyRegion && !buyRegion.isSold())) {
messageBridge.message(sender, "addfriend-noOwner", region);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(friend -> {
if (friend.hasPlayedBefore() && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
} else if (region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
} else if (region.isOwner(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
} else if (region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "addfriend-successOther", friend.getName(), region);
}
}, this.executor);
return;
}
if (!sender.hasPermission("areashop.addfriend") || !(sender instanceof Player player)) {
messageBridge.message(sender, "addfriend-noPermission", region);
return;
}
if (!region.isOwner(player)) {
messageBridge.message(sender, "addfriend-noPermissionOther", region);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(friend -> {
if (friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
} else if (region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
} else if (region.isOwner(friend.getUniqueId())) {
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
} else if (region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "addfriend-success", friend.getName(), region);
}
}, this.executor);
}
@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());
}
} else if (toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
}
@@ -1,12 +1,14 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.SignUtils;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -15,8 +17,6 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.BlockIterator;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -28,13 +28,11 @@ public class AddsignCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private SignManager signManager;
@Inject
private Plugin plugin;
@Inject
private BukkitInterface bukkitInterface;
@Override
public String getCommandStart() {
@@ -55,11 +53,10 @@ public class AddsignCommand extends CommandAreaShop {
messageBridge.message(sender, "addsign-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
// Get the sign
Block block = null;
@@ -111,7 +108,7 @@ public class AddsignCommand extends CommandAreaShop {
return;
}
region.getSignsFeature().addSign(block.getLocation(), block.getType(), bukkitInterface.getSignFacing(block), profile);
region.getSignsFeature().addSign(block.getLocation(), block.getType(), SignUtils.getSignFacing(block), profile);
if(profile == null) {
messageBridge.message(sender, "addsign-success", region);
} else {
@@ -1,15 +1,15 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -21,7 +21,7 @@ public class BuyCommand extends CommandAreaShop {
@Inject
private Plugin plugin;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -42,11 +42,10 @@ public class BuyCommand extends CommandAreaShop {
messageBridge.message(sender, "buy-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(args.length > 1 && args[1] != null) {
BuyRegion region = fileManager.getBuy(args[1]);
if(region == null) {
@@ -1,10 +1,12 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
@@ -12,8 +14,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
@@ -26,7 +26,7 @@ public class DelCommand extends CommandAreaShop {
@Inject
private WorldEditInterface worldEditInterface;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -53,11 +53,10 @@ public class DelCommand extends CommandAreaShop {
}
if(args.length < 2) {
// Only players can have a selection
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
@@ -1,130 +1,134 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class DelfriendCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
@Override
public String getCommandStart() {
return "areashop delfriend";
}
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.delfriendall") || target.hasPermission("areashop.delfriend")) {
return "help-delFriend";
}
return null;
}
@Inject
private OfflinePlayerHelper offlinePlayerHelper;
/**
* 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
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(person.hasPermission("areashop.delfriendall")) {
return true;
}
if(person instanceof Player) {
Player player = (Player)person;
return region.isOwner(player) && player.hasPermission("areashop.delfriend");
}
return false;
}
@Inject
private BukkitSchedulerExecutor executor;
@SuppressWarnings("deprecation")
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
messageBridge.message(sender, "delfriend-noPermission");
return;
}
if(args.length < 2) {
messageBridge.message(sender, "delfriend-help");
return;
}
GeneralRegion region;
if(args.length <= 2) {
if(sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = fileManager.getRegion(args[2]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if(sender.hasPermission("areashop.delfriendall")) {
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
messageBridge.message(sender, "delfriend-noOwner", region);
return;
}
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
return;
}
if(region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "delfriend-successOther", friend.getName(), region);
}
} else {
if(sender.hasPermission("areashop.delfriend") && sender instanceof Player) {
if(region.isOwner((Player)sender)) {
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
return;
}
if(region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "delfriend-success", friend.getName(), region);
}
} else {
messageBridge.message(sender, "delfriend-noPermissionOther", region);
}
} else {
messageBridge.message(sender, "delfriend-noPermission", region);
}
}
}
@Override
public String getCommandStart() {
return "areashop delfriend";
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.delfriendall") || target.hasPermission("areashop.delfriend")) {
return "help-delFriend";
}
return null;
}
/**
* 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
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if (person.hasPermission("areashop.delfriendall")) {
return true;
}
if (person instanceof Player player) {
return region.isOwner(player) && player.hasPermission("areashop.delfriend");
}
return false;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
messageBridge.message(sender, "delfriend-noPermission");
return;
}
if (args.length < 2) {
messageBridge.message(sender, "delfriend-help");
return;
}
GeneralRegion region;
if (args.length == 2) {
if (!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
region = fileManager.getRegion(args[2]);
if (region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if (sender.hasPermission("areashop.delfriendall")) {
if ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
|| (region instanceof BuyRegion buyRegion && !buyRegion.isSold())) {
messageBridge.message(sender, "delfriend-noOwner", region);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(friend -> {
if (!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
return;
}
if (region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "delfriend-successOther", friend.getName(), region);
}
}, this.executor);
return;
}
if (!sender.hasPermission("areashop.delfriend") || !(sender instanceof Player player)) {
messageBridge.message(sender, "delfriend-noPermission", region);
return;
}
if (!region.isOwner(player)) {
messageBridge.message(sender, "delfriend-noPermissionOther", region);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(friend -> {
if (!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
} else if (region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
region.update();
messageBridge.message(sender, "delfriend-success", friend.getName(), region);
}
}, this.executor);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
@@ -1,9 +1,10 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.tools.Materials;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -11,8 +12,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -44,18 +43,17 @@ public class DelsignCommand extends CommandAreaShop {
messageBridge.message(sender, "delsign-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
// 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) {
if(!next.getType().isAir()) {
block = next;
}
}
@@ -70,8 +68,9 @@ public class DelsignCommand extends CommandAreaShop {
}
RegionSign regionSign = optionalSign.get();
messageBridge.message(sender, "delsign-success", regionSign.getRegion());
signManager.removeSign(regionSign);
regionSign.remove();
// Sometimes the RegionSign data is corrupted. Forcefully set the block to air
block.setType(Material.AIR);
}
@Override
@@ -1,7 +1,9 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.RegionGroup;
import me.wiefferink.areashop.regions.RentRegion;
@@ -11,13 +13,12 @@ import net.milkbowl.vault.economy.Economy;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@Singleton
public class FindCommand extends CommandAreaShop {
@@ -27,7 +28,7 @@ public class FindCommand extends CommandAreaShop {
@Inject
private Economy economy;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -48,7 +49,7 @@ public class FindCommand extends CommandAreaShop {
messageBridge.message(sender, "find-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
@@ -56,7 +57,6 @@ public class FindCommand extends CommandAreaShop {
messageBridge.message(sender, "find-help");
return;
}
Player player = (Player)sender;
double balance = 0.0;
if(economy != null) {
balance = economy.getBalance(player);
@@ -97,7 +97,7 @@ public class FindCommand extends CommandAreaShop {
}
if(!results.isEmpty()) {
// Draw a random one
BuyRegion region = results.get(new Random().nextInt(results.size()));
BuyRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
@@ -137,7 +137,7 @@ public class FindCommand extends CommandAreaShop {
}
if(!results.isEmpty()) {
// Draw a random one
RentRegion region = results.get(new Random().nextInt(results.size()));
RentRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
@@ -1,9 +1,11 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
@@ -11,8 +13,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
@@ -23,7 +23,7 @@ public class GroupaddCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private RegionFactory regionFactory;
@Inject
@@ -59,11 +59,10 @@ public class GroupaddCommand extends CommandAreaShop {
fileManager.addGroup(group);
}
if(args.length == 2) {
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
@@ -1,9 +1,11 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
@@ -11,8 +13,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
@@ -23,7 +23,7 @@ public class GroupdelCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private RegionFactory regionFactory;
@Inject
@@ -59,11 +59,10 @@ public class GroupdelCommand extends CommandAreaShop {
}
if(args.length == 2) {
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
@@ -1,13 +1,13 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RegionGroup;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -18,7 +18,7 @@ public class GroupinfoCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,12 +1,12 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -16,7 +16,7 @@ public class GrouplistCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,13 +1,12 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.regions.ImportJob;
import me.wiefferink.areashop.regions.ImportJobFactory;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -1,23 +1,21 @@
package me.wiefferink.areashop.commands;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -30,7 +28,7 @@ public class InfoCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -43,12 +43,11 @@ public class LinksignsCommand extends CommandAreaShop {
messageBridge.message(sender, "linksigns-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(signLinkerManager.isInSignLinkMode(player)) {
signLinkerManager.exitSignLinkMode(player);
} else {
@@ -1,18 +1,19 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -24,7 +25,13 @@ public class MeCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private OfflinePlayerHelper offlinePlayerHelper;
@Inject
private BukkitSchedulerExecutor executor;
@Override
public String getCommandStart() {
@@ -55,42 +62,48 @@ public class MeCommand extends CommandAreaShop {
player = (OfflinePlayer)sender;
}
if(args.length > 1) {
player = Bukkit.getOfflinePlayer(args[1]);
if(!player.hasPlayedBefore()) {
messageBridge.message(sender, "me-noPlayer", args[1]);
return;
}
}
if(!player.hasPlayedBefore()) {
// Lookup offline players async
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(offlinePlayer -> {
if (!offlinePlayer.hasPlayedBefore()) {
messageBridge.message(sender, "me-noPlayer", args[1]);
} else {
sendMessageAboutRegions(sender, offlinePlayer);
}
}, this.executor);
return;
}
sendMessageAboutRegions(sender, player);
}
private void sendMessageAboutRegions(CommandSender sender, OfflinePlayer target) {
// Get the regions owned by the player
Set<RentRegion> rentRegions = new HashSet<>();
for(RentRegion region : fileManager.getRentsRef()) {
if(region.isOwner(player)) {
if(region.isOwner(target)) {
rentRegions.add(region);
}
}
Set<BuyRegion> buyRegions = new HashSet<>();
for(BuyRegion region : fileManager.getBuysRef()) {
if(region.isOwner(player)) {
if(region.isOwner(target)) {
buyRegions.add(region);
}
}
// Get the regions the player is added as friend
Set<GeneralRegion> friendRegions = new HashSet<>();
for(GeneralRegion region : fileManager.getRegionsRef()) {
if(region.getFriendsFeature().getFriends().contains(player.getUniqueId())) {
if(region.getFriendsFeature().getFriends().contains(target.getUniqueId())) {
friendRegions.add(region);
}
}
// Send messages
boolean foundSome = !rentRegions.isEmpty() || !buyRegions.isEmpty() || !friendRegions.isEmpty();
if(foundSome) {
messageBridge.message(sender, "me-header", player.getName());
if(!foundSome) {
messageBridge.message(sender, "me-nothing", target.getName());
return;
}
messageBridge.message(sender, "me-header", target.getName());
if(!rentRegions.isEmpty()) {
for(RentRegion region : rentRegions) {
messageBridge.messageNoPrefix(sender, "me-rentLine", region);
@@ -106,12 +119,7 @@ public class MeCommand extends CommandAreaShop {
messageBridge.messageNoPrefix(sender, "me-friendLine", region);
}
}
if(!foundSome) {
messageBridge.message(sender, "me-nothing", player.getName());
} else {
messageBridge.messageNoPrefix(sender, "me-clickHint");
}
messageBridge.messageNoPrefix(sender, "me-clickHint");
}
@Override
@@ -1,5 +1,7 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
@@ -8,8 +10,6 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -1,12 +1,11 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class ReloadCommand extends CommandAreaShop {
@@ -1,14 +1,14 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -18,7 +18,7 @@ public class RentCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -39,11 +39,10 @@ public class RentCommand extends CommandAreaShop {
messageBridge.message(sender, "rent-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(args.length > 1 && args[1] != null) {
RentRegion rent = fileManager.getRent(args[1]);
if(rent == null) {
@@ -1,14 +1,14 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -18,7 +18,7 @@ public class ResellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,15 +1,15 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -20,7 +20,7 @@ public class SchematiceventCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,15 +1,15 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -19,7 +19,7 @@ public class SellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -44,8 +44,7 @@ public class SellCommand extends CommandAreaShop {
if(person.hasPermission("areashop.sell")) {
return true;
}
if(person instanceof Player) {
Player player = (Player)person;
if(person instanceof Player player) {
return region.isOwner(player) && person.hasPermission("areashop.sellown");
}
return false;
@@ -59,9 +58,9 @@ public class SellCommand extends CommandAreaShop {
}
BuyRegion buy;
if(args.length <= 1) {
if(sender instanceof Player) {
if(sender instanceof Player player) {
// get the region by location
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
List<BuyRegion> regions = Utils.getImportantBuyRegions((player).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
@@ -0,0 +1,77 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class SetTransferCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop settransfer";
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.settransfer")) {
return "help-settransfer";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.settransfer")) {
messageBridge.message(sender, "settransfer-noPermission");
return;
}
if (args.length <= 2 || args[1] == null || args[2] == null) {
messageBridge.message(sender, "settransfer-help");
return;
}
GeneralRegion region = fileManager.getRegion(args[1]);
if (region == null) {
messageBridge.message(sender, "settransfer-notRegistered", args[1]);
return;
}
boolean value;
if (args[2].equalsIgnoreCase("true")) {
value = true;
} else if (args[2].equalsIgnoreCase("false")) {
value = false;
} else {
messageBridge.message(sender, "settransfer-invalidSetting", args[2]);
return;
}
region.setTransferEnabled(value);
messageBridge.message(sender, "settransfer-success", args[2], region);
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if (toComplete == 2) {
result = fileManager.getRegionNames();
} else if (toComplete == 3) {
result.add("true");
result.add("false");
}
return result;
}
}
@@ -1,15 +1,15 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -19,7 +19,7 @@ public class SetdurationCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private Plugin plugin;
@@ -1,97 +1,100 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class SetlandlordCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
@Override
public String getCommandStart() {
return "areashop setlandlord";
}
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private OfflinePlayerHelper offlinePlayerHelper;
@Inject
private BukkitSchedulerExecutor executor;
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setlandlord")) {
return "help-setlandlord";
}
return null;
}
@Override
public String getCommandStart() {
return "areashop setlandlord";
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setlandlord")) {
messageBridge.message(sender, "setlandlord-noPermission");
return;
}
if(args.length < 2) {
messageBridge.message(sender, "setlandlord-help");
return;
}
@SuppressWarnings("deprecation")
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
GeneralRegion region;
if(args.length < 3) {
if(sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = fileManager.getRegion(args[2]);
}
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
String playerName = player.getName();
if(playerName == null || playerName.isEmpty()) {
playerName = args[1];
}
region.setLandlord(player.getUniqueId(), playerName);
region.update();
messageBridge.message(sender, "setlandlord-success", playerName, region);
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.setlandlord")) {
return "help-setlandlord";
}
return null;
}
@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());
}
} else if(toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.setlandlord")) {
messageBridge.message(sender, "setlandlord-noPermission");
return;
}
if (args.length < 2) {
messageBridge.message(sender, "setlandlord-help");
return;
}
GeneralRegion region;
if (args.length < 3) {
if (!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
region = fileManager.getRegion(args[2]);
}
if (region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(args[1]).thenAcceptAsync(offlinePlayer -> {
String playerName = offlinePlayer.getName();
if (playerName == null || playerName.isEmpty()) {
playerName = args[1];
}
region.setLandlord(offlinePlayer.getUniqueId(), playerName);
region.update();
messageBridge.message(sender, "setlandlord-success", playerName, region);
}, this.executor);
}
@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());
}
} else if (toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
}
@@ -1,18 +1,18 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@@ -21,118 +21,116 @@ import java.util.UUID;
@Singleton
public class SetownerCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
@Override
public String getCommandStart() {
return "areashop setowner";
}
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private OfflinePlayerHelper offlinePlayerHelper;
@Inject
private BukkitSchedulerExecutor executor;
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
return "help-setowner";
}
return null;
}
@Override
public String getCommandStart() {
return "areashop setowner";
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
messageBridge.message(sender, "setowner-noPermission");
return;
}
GeneralRegion region;
if(args.length < 2) {
messageBridge.message(sender, "setowner-help");
return;
}
if(args.length == 2) {
if(sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = fileManager.getRegion(args[2]);
}
if(region == null) {
messageBridge.message(sender, "setowner-notRegistered");
return;
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
return "help-setowner";
}
return null;
}
if(region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
messageBridge.message(sender, "setowner-noPermissionRent", region);
return;
}
if(region instanceof BuyRegion && !sender.hasPermission("areashop.setownerbuy")) {
messageBridge.message(sender, "setowner-noPermissionBuy", region);
return;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
messageBridge.message(sender, "setowner-noPermission");
return;
}
GeneralRegion region;
if (args.length < 2) {
messageBridge.message(sender, "setowner-help");
return;
}
if (args.length == 2) {
if (!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
// get the region by location
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
UUID uuid = null;
@SuppressWarnings("deprecation")
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
if(player != null) {
uuid = player.getUniqueId();
}
if(uuid == null) {
messageBridge.message(sender, "setowner-noPlayer", args[1], region);
return;
}
} else {
region = fileManager.getRegion(args[2]);
}
if (region == null) {
messageBridge.message(sender, "setowner-notRegistered");
return;
}
if(region instanceof RentRegion) {
RentRegion rent = (RentRegion)region;
if(rent.isRenter(uuid)) {
// extend
rent.setRentedUntil(rent.getRentedUntil() + rent.getDuration());
rent.setRenter(uuid);
messageBridge.message(sender, "setowner-succesRentExtend", region);
} else {
// change
if(!rent.isRented()) {
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
}
rent.setRenter(uuid);
messageBridge.message(sender, "setowner-succesRent", region);
}
}
if(region instanceof BuyRegion) {
BuyRegion buy = (BuyRegion)region;
buy.setBuyer(uuid);
messageBridge.message(sender, "setowner-succesBuy", region);
}
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
region.update();
region.saveRequired();
}
if (region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
messageBridge.message(sender, "setowner-noPermissionRent", region);
return;
}
if (region instanceof BuyRegion && !sender.hasPermission("areashop.setownerbuy")) {
messageBridge.message(sender, "setowner-noPermissionBuy", region);
return;
}
@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());
}
} else if(toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
this.offlinePlayerHelper.lookupUuidAsync(args[1]).thenAcceptAsync(optionalUuid -> {
if (optionalUuid.isEmpty()) {
messageBridge.message(sender, "setowner-noPlayer", args[1], region);
return;
}
final UUID uuid = optionalUuid.get();
if (region instanceof RentRegion rent) {
if (rent.isRenter(uuid)) {
// extend
rent.setRentedUntil(rent.getRentedUntil() + rent.getDuration());
rent.setRenter(uuid);
messageBridge.message(sender, "setowner-succesRentExtend", region);
} else {
// change
if (!rent.isRented()) {
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
}
rent.setRenter(uuid);
messageBridge.message(sender, "setowner-succesRent", region);
}
}
if (region instanceof BuyRegion buy) {
buy.setBuyer(uuid);
messageBridge.message(sender, "setowner-succesBuy", region);
}
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
region.update();
region.saveRequired();
}, this.executor);
}
@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());
}
} else if (toComplete == 3) {
result.addAll(fileManager.getRegionNames());
}
return result;
}
}
@@ -1,7 +1,9 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
@@ -9,8 +11,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -20,7 +20,7 @@ public class SetpriceCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,13 +1,14 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -17,7 +18,7 @@ public class SetrestoreCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private Plugin plugin;
@@ -79,7 +80,10 @@ public class SetrestoreCommand extends CommandAreaShop {
result.add("false");
result.add("general");
} else if(toComplete == 4) {
result.addAll(plugin.getConfig().getConfigurationSection("schematicProfiles").getKeys(false));
ConfigurationSection schemProfiles = fileManager.getConfig().getConfigurationSection("schematicProfiles");
if (schemProfiles != null) {
result.addAll(schemProfiles.getKeys(false));
}
}
return result;
}
@@ -1,8 +1,10 @@
package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
@@ -10,8 +12,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -21,7 +21,7 @@ public class SetteleportCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -43,10 +43,9 @@ public class SetteleportCommand extends CommandAreaShop {
* @return true if the person can set the teleport location, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(!(person instanceof Player)) {
if(!(person instanceof Player player)) {
return false;
}
Player player = (Player)person;
return player.hasPermission("areashop.setteleportall")
|| region.isOwner(player) && player.hasPermission("areashop.setteleport");
}
@@ -57,11 +56,10 @@ public class SetteleportCommand extends CommandAreaShop {
messageBridge.message(sender, "setteleport-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "onlyByPlayer");
return;
}
Player player = (Player)sender;
GeneralRegion region;
if(args.length < 2) {
// get the region by location
@@ -2,13 +2,15 @@ package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
@@ -22,8 +24,6 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -33,7 +33,7 @@ public class StackCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Inject
private WorldEditInterface worldEditInterface;
@Inject
@@ -64,11 +64,10 @@ public class StackCommand extends CommandAreaShop {
return;
}
// Only from ingame
if(!(sender instanceof Player)) {
if(!(sender instanceof final Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
final Player player = (Player)sender;
// Specify enough arguments
if(args.length < 5) {
messageBridge.message(sender, "stack-help");
@@ -1,14 +1,14 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -18,7 +18,7 @@ public class StopresellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -1,13 +1,13 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -17,7 +17,7 @@ public class TeleportCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -39,10 +39,9 @@ public class TeleportCommand extends CommandAreaShop {
* @return true if the person can teleport to it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(!(person instanceof Player)) {
if(!(person instanceof Player player)) {
return false;
}
Player player = (Player)person;
return player.hasPermission("areashop.teleportall")
|| region.isOwner(player) && player.hasPermission("areashop.teleport")
|| region.isAvailable() && player.hasPermission("areashop.teleportavailable")
@@ -55,7 +54,7 @@ public class TeleportCommand extends CommandAreaShop {
messageBridge.message(sender, "teleport-noPermission");
return;
}
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
@@ -63,7 +62,6 @@ public class TeleportCommand extends CommandAreaShop {
messageBridge.message(sender, "teleport-help");
return;
}
Player player = (Player)sender;
GeneralRegion region = fileManager.getRegion(args[1]);
if(region == null) {
messageBridge.message(player, "teleport-noRentOrBuy", args[1]);
@@ -0,0 +1,150 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.IFileManager;
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.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@Singleton
public class TransferCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private Plugin plugin;
@Inject
private Server server;
@Override
public String getCommandStart() {
return "areashop transfer";
}
@Override
public String getHelp(CommandSender target) {
if (!target.hasPermission("areashop.transfer")) {
return null;
}
return "help-transfer";
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.transfer")) {
this.messageBridge.message(sender, "transfer-noPermission");
return;
}
if (sender instanceof Player player) {
handlePlayer(player, args);
} else {
this.messageBridge.message(sender, "cmd-onlyByPlayer");
}
}
private void handlePlayer(Player player, String[] args) {
if (args.length < 2) {
this.messageBridge.message(player, "transfer-help");
return;
}
String targetPlayerName = args[1];
if (targetPlayerName.equals(player.getName())) {
this.messageBridge.message(player, "transfer-transferSelf");
return;
}
GeneralRegion region;
if (args.length > 2) {
String targetRegionName = args[2];
region = this.fileManager.getRegion(targetRegionName);
if (region == null) {
messageBridge.message(player, "cmd-noRegion");
return;
}
} else {
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
messageBridge.message(player, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
messageBridge.message(player, "cmd-moreRegionsAtLocation");
return;
}
region = regions.get(0);
}
if (!region.isTransferEnabled()) {
this.messageBridge.message(player, "transfer-disabled");
return;
}
@SuppressWarnings("deprecation")
OfflinePlayer targetPlayer = this.server.getOfflinePlayer(targetPlayerName);
if (!targetPlayer.hasPlayedBefore()) {
// Unknown player
this.messageBridge.message(player, "transfer-noPlayer", targetPlayerName);
return;
}
if (region.isLandlord(player.getUniqueId())) {
// Transfer ownership if same as landlord
region.setOwner(targetPlayer.getUniqueId());
region.setLandlord(targetPlayer.getUniqueId(), targetPlayerName);
this.messageBridge.message(player, "transfer-transferred-owner", targetPlayerName, region);
if (targetPlayer.isOnline()) {
this.messageBridge.message(targetPlayer.getPlayer(), "transfer-transferred-owner", targetPlayerName, region);
}
return;
}
if (!region.isOwner(player.getUniqueId())) {
// Cannot transfer tenant if we aren't the current tenant
this.messageBridge.message(player, "transfer-notCurrentTenant");
return;
}
// Swap the owner/occupant (renter or buyer)
region.setOwner(targetPlayer.getUniqueId());
this.messageBridge.message(player, "transfer-transferred-tenant", targetPlayerName, region);
if (targetPlayer.isOnline()) {
this.messageBridge.message(targetPlayer.getPlayer(), "transfer-transferred-tenant", targetPlayerName, region);
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
if (toComplete == 2) {
Collection<? extends Player> players = this.server.getOnlinePlayers();
List<String> ret = new ArrayList<>(players.stream()
.map(Player::getName)
.toList());
if (sender instanceof Player player) {
ret.remove(player.getName());
}
return ret;
} else if (toComplete == 3) {
if (!(sender instanceof Player player)) {
return this.fileManager.getRegionNames();
}
UUID uuid = player.getUniqueId();
return new ArrayList<>(this.fileManager.getRegions()
.stream()
.filter(region -> region.isOwner(uuid) || region.isLandlord(uuid))
.map(GeneralRegion::getName)
.toList());
}
return Collections.emptyList();
}
}
@@ -1,15 +1,15 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
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;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -19,7 +19,7 @@ public class UnrentCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private FileManager fileManager;
private IFileManager fileManager;
@Override
public String getCommandStart() {
@@ -44,8 +44,7 @@ public class UnrentCommand extends CommandAreaShop {
if(person.hasPermission("areashop.unrent")) {
return true;
}
if(person instanceof Player) {
Player player = (Player)person;
if(person instanceof Player player) {
return region.isOwner(player) && person.hasPermission("areashop.unrentown");
}
return false;
@@ -1,5 +1,7 @@
package me.wiefferink.areashop.features;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
@@ -21,8 +23,6 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;
@Singleton
@@ -1,5 +1,7 @@
package me.wiefferink.areashop.features;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
@@ -20,8 +22,6 @@ import me.wiefferink.areashop.tools.Utils;
import org.bukkit.event.EventHandler;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class DebugFeature extends RegionFeature {
@@ -3,6 +3,7 @@ package me.wiefferink.areashop.features;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import jakarta.inject.Inject;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
@@ -19,7 +20,6 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
@@ -5,6 +5,8 @@ import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
import me.wiefferink.areashop.interfaces.RegionAccessSet;
@@ -15,8 +17,6 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@@ -6,11 +6,11 @@ import com.google.inject.assistedinject.AssistedInject;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.SignUtils;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.Bukkit;
@@ -37,7 +37,6 @@ public class RegionSign {
private final BlockBehaviourHelper blockHelper;
private final SignErrorLogger errorLogger;
private final BukkitInterface bukkitInterface;
private final SignsFeature signsFeature;
private final String key;
@@ -47,13 +46,11 @@ public class RegionSign {
RegionSign(
@Nonnull BlockBehaviourHelper blockBehaviourHelper,
@Nonnull SignErrorLogger signErrorLogger,
@Nonnull BukkitInterface bukkitInterface,
@Assisted @Nonnull SignsFeature signsFeature,
@Assisted @Nonnull String key
) {
this.blockHelper = blockBehaviourHelper;
this.errorLogger = signErrorLogger;
this.bukkitInterface = bukkitInterface;
this.signsFeature = signsFeature;
this.key = key;
}
@@ -98,8 +95,11 @@ public class RegionSign {
* Remove this sign from the region.
*/
public void remove() {
getLocation().getBlock().setType(Material.AIR);
this.signsFeature.signManager().removeSign(this);
Location location = getLocation();
if (location != null && location.getWorld() != null) {
location.getBlock().setType(Material.AIR);
this.signsFeature.signManager().removeSign(this);
}
getRegion().setSetting("general.signs." + key, null);
// Remove the sign from the region's sign manager
}
@@ -177,7 +177,9 @@ public class RegionSign {
if(!Materials.isSign(block.getType())) {
Material signType = getMaterial();
if (!blockHelper.canPlace(block.getLocation(), Bukkit.createBlockData(signType))) {
AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, could not set sign block back");
errorLogger.submitWarning("Setting sign" + key + "of region" + getRegion().getName() + "failed, could not set sign block back");
this.remove();
return false;
}
// Don't do physics here, we first need to update the direction
block.setType(signType, false);
@@ -190,7 +192,7 @@ public class RegionSign {
} else if(blockData instanceof org.bukkit.block.data.type.Sign) {
((org.bukkit.block.data.type.Sign) blockData).setRotation(getFacing());
} else {
AreaShop.warn("Failed to update the facing direction of the sign at", getStringLocation(), "to ", getFacing(), ", region:", getRegion().getName());
errorLogger.submitWarning("Failed to update the facing direction of the sign at" + getStringLocation() + "to " + getFacing() + ", region:" + getRegion().getName());
return false;
}
block.setBlockData(blockData);
@@ -206,7 +208,7 @@ public class RegionSign {
getRegion().setSetting("general.signs." + key + ".signType", block.getType().name());
}
if(!regionConfig.isString("general.signs." + key + ".facing")) {
BlockFace signFacing = bukkitInterface.getSignFacing(block);
BlockFace signFacing = SignUtils.getSignFacing(block);
getRegion().setSetting("general.signs." + key + ".facing", signFacing == null ? null : signFacing.toString());
}
@@ -3,11 +3,13 @@ package me.wiefferink.areashop.features.signs;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.github.bakedlibs.dough.blocks.ChunkPosition;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
@@ -40,7 +42,7 @@ public class SignCache {
BlockPosition blockPosition = regionSign.getPosition();
this.allSigns.put(blockPosition.getPosition(), regionSign);
ChunkPosition chunkPosition = new ChunkPosition(blockPosition.getChunk());
Collection<RegionSign> signs = this.signsByChunk.computeIfAbsent(chunkPosition.getPosition(), x -> new ArrayList<>());
Collection<RegionSign> signs = this.signsByChunk.computeIfAbsent(chunkPosition.getPosition(), x -> new HashSet<>());
signs.add(regionSign);
}
@@ -51,8 +53,9 @@ public class SignCache {
public Optional<RegionSign> removeSign(BlockPosition position) {
RegionSign removed = this.allSigns.remove(position.getPosition());
if (removed != null) {
Location location = position.toLocation();
this.signsByChunk.remove(new ChunkPosition(location).getPosition());
World world = position.getWorld();
ChunkPosition chunkPosition = new ChunkPosition(world, position.getChunkX(), position.getChunkZ());
this.signsByChunk.remove(chunkPosition.getPosition());
// Remove the sign from the region
}
return Optional.ofNullable(removed);
@@ -7,16 +7,16 @@ import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.SignUtils;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import org.bukkit.Chunk;
@@ -47,10 +47,9 @@ public class SignListener implements Listener {
private final MessageBridge messageBridge;
private final SignManager signManager;
private final SignLinkerManager signLinkerManager;
private final BukkitInterface bukkitInterface;
private final WorldGuardInterface worldGuardInterface;
private final RegionFactory regionFactory;
private final FileManager fileManager;
private final IFileManager fileManager;
public SignListener(
@Nonnull AreaShop plugin,
@@ -58,25 +57,23 @@ public class SignListener implements Listener {
@Nonnull RegionFactory regionFactory,
@Nonnull MessageBridge messageBridge,
@Nonnull SignLinkerManager signLinkerManager,
@Nonnull BukkitInterface bukkitInterface,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull SignManager signManager,
@Nonnull FileManager fileManager) {
@Nonnull IFileManager fileManager) {
this.fileManager = fileManager;
this.signManager = signManager;
this.signLinkerManager = signLinkerManager;
this.regionFactory = regionFactory;
this.behaviourHelper = behaviourHelper;
this.plugin = plugin;
this.bukkitInterface = bukkitInterface;
this.worldGuardInterface = worldGuardInterface;
this.messageBridge = messageBridge;
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void regionUpdate(UpdateRegionEvent event) {
Optional<SignsFeature> signsFeature = event.getRegion().getFeature(SignsFeature.class);
signsFeature.map(SignsFeature::signManager).ifPresent(SignManager::update);
SignsFeature signsFeature = event.getRegion().getSignsFeature();
signsFeature.signManager().update();
}
@@ -92,7 +89,6 @@ public class SignListener implements Listener {
if(chunkSigns.isEmpty()) {
return;
}
chunkSigns.remove(null);
Do.forAll(chunkSigns, RegionSign::update);
}
@@ -252,14 +248,14 @@ public class SignListener implements Listener {
return;
}
FileManager.AddResult addResult = fileManager.checkRegionAdd(player, regionManager.getRegion(secondLine), event.getPlayer().getWorld(), GeneralRegion.RegionType.RENT);
if(addResult == FileManager.AddResult.BLACKLISTED) {
IFileManager.AddResult addResult = fileManager.checkRegionAdd(player, regionManager.getRegion(secondLine), event.getPlayer().getWorld(), GeneralRegion.RegionType.RENT);
if(addResult == IFileManager.AddResult.BLACKLISTED) {
messageBridge.message(player, "setup-blacklisted", secondLine);
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
} else if(addResult == IFileManager.AddResult.ALREADYADDED) {
messageBridge.message(player, "setup-alreadyRentSign");
} else if(addResult == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
} else if(addResult == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
messageBridge.message(player, "setup-alreadyOtherWorld");
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
} else if(addResult == IFileManager.AddResult.NOPERMISSION) {
messageBridge.message(player, "setup-noPermission", secondLine);
} else if(thirdLine != null && !thirdLine.isEmpty() && !Utils.checkTimeFormat(thirdLine)) {
messageBridge.message(player, "setup-wrongDuration");
@@ -292,7 +288,7 @@ public class SignListener implements Listener {
if(durationSet) {
rent.setDuration(thirdLine);
}
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), bukkitInterface.getSignFacing(event.getBlock()), null);
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(rent);
if (addingRegionEvent.isCancelled()) {
@@ -357,14 +353,14 @@ public class SignListener implements Listener {
messageBridge.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) {
IFileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, region, event.getPlayer().getWorld(), GeneralRegion.RegionType.BUY);
if(addResult == IFileManager.AddResult.BLACKLISTED) {
messageBridge.message(player, "setup-blacklisted", secondLine);
} else if(addResult == FileManager.AddResult.ALREADYADDED) {
} else if(addResult == IFileManager.AddResult.ALREADYADDED) {
messageBridge.message(player, "setup-alreadyRentSign");
} else if(addResult == FileManager.AddResult.ALREADYADDEDOTHERWORLD) {
} else if(addResult == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
messageBridge.message(player, "setup-alreadyOtherWorld");
} else if(addResult == FileManager.AddResult.NOPERMISSION) {
} else if(addResult == IFileManager.AddResult.NOPERMISSION) {
messageBridge.message(player, "setup-noPermission", secondLine);
} else {
double price = 0.0;
@@ -392,7 +388,7 @@ public class SignListener implements Listener {
if(priceSet) {
buy.setPrice(price);
}
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), bukkitInterface.getSignFacing(event.getBlock()), null);
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(buy);
if (addingRegionEvent.isCancelled()) {
@@ -438,10 +434,10 @@ public class SignListener implements Listener {
}
if(thirdLine == null || thirdLine.isEmpty()) {
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), bukkitInterface.getSignFacing(event.getBlock()), null);
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
messageBridge.message(player, "addsign-success", region);
} else {
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), bukkitInterface.getSignFacing(event.getBlock()), thirdLine);
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), thirdLine);
messageBridge.message(player, "addsign-successProfile", thirdLine, region);
}
@@ -1,6 +1,7 @@
package me.wiefferink.areashop.features.signs;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.managers.Manager;
import org.bukkit.Location;
import org.bukkit.World;
@@ -52,11 +53,22 @@ public class SignManager extends Manager {
}
public void removeSign(RegionSign regionSign) {
removeSign(regionSign.getLocation());
Location location = regionSign.getLocation();
if (location.getWorld() == null) {
return;
}
cacheForWorld(location.getWorld()).removeSign(regionSign);
}
public Optional<RegionSign> removeSign(Location location) {
return getCacheForWorld(location.getWorld()).flatMap(cache -> cache.removeSign(location));
if (location == null || location.getWorld() == null) {
return Optional.empty();
}
return removeSign(new BlockPosition(location));
}
public Optional<RegionSign> removeSign(BlockPosition blockPosition) {
return getCacheForWorld(blockPosition.getWorld()).flatMap(cache -> cache.removeSign(blockPosition));
}
/**
@@ -65,9 +77,10 @@ public class SignManager extends Manager {
*/
public boolean update() {
boolean result = true;
for (SignCache signCache : this.signCacheMap.values())
for(RegionSign sign : signCache.allSigns()) {
result &= sign.update();
for (SignCache signCache : this.signCacheMap.values()) {
for (RegionSign sign : signCache.allSigns()) {
result &= sign.update();
}
}
return result;
}
@@ -94,6 +107,7 @@ public class SignManager extends Manager {
public void shutdown() {
update();
this.signCacheMap.values().forEach(SignCache::clear);
this.signCacheMap.clear();
}
@@ -2,6 +2,8 @@ package me.wiefferink.areashop.features.signs;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.github.bakedlibs.dough.blocks.ChunkPosition;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.RegionFeature;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -12,6 +14,8 @@ import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
public class SignsFeature extends RegionFeature {
@@ -34,17 +38,18 @@ public class SignsFeature extends RegionFeature {
setRegion(region);
// Setup current signs
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
if(signSection != null) {
for(String signKey : signSection.getKeys(false)) {
RegionSign sign = signFactory.createRegionSign(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;
}
this.globalSignManager.cacheForWorld(location.getWorld()).addSign(sign);
this.internalSignManager.addSign(sign);
if (signSection == null) {
return;
}
for(String signKey : signSection.getKeys(false)) {
RegionSign sign = signFactory.createRegionSign(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;
}
this.globalSignManager.cacheForWorld(location.getWorld()).addSign(sign);
this.internalSignManager.addSign(sign);
}
}
@@ -6,11 +6,10 @@ import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.RegionFactory;
import javax.annotation.Nonnull;
@@ -30,10 +29,9 @@ public class SignsModule extends AbstractModule {
@Nonnull RegionFactory regionFactory,
@Nonnull MessageBridge messageBridge,
@Nonnull SignLinkerManager signLinkerManager,
@Nonnull BukkitInterface bukkitInterface,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull SignManager signManager,
@Nonnull FileManager fileManager
@Nonnull IFileManager fileManager
) {
final SignListener signListener = new SignListener(
plugin,
@@ -41,7 +39,6 @@ public class SignsModule extends AbstractModule {
regionFactory,
messageBridge,
signLinkerManager,
bukkitInterface,
worldGuardInterface,
signManager,
fileManager
@@ -1,6 +1,8 @@
package me.wiefferink.areashop.managers;
import com.google.inject.Injector;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.AddCommand;
@@ -27,6 +29,7 @@ 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.SetTransferCommand;
import me.wiefferink.areashop.commands.SetdurationCommand;
import me.wiefferink.areashop.commands.SetlandlordCommand;
import me.wiefferink.areashop.commands.SetownerCommand;
@@ -36,6 +39,7 @@ 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.TransferCommand;
import me.wiefferink.areashop.commands.UnrentCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -43,8 +47,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
@@ -70,6 +72,7 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
commands.add(injector.getInstance(UnrentCommand.class));
commands.add(injector.getInstance(BuyCommand.class));
commands.add(injector.getInstance(SellCommand.class));
commands.add(injector.getInstance(TransferCommand.class));
commands.add(injector.getInstance(MeCommand.class));
commands.add(injector.getInstance(InfoCommand.class));
commands.add(injector.getInstance(TeleportCommand.class));
@@ -83,6 +86,7 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
commands.add(injector.getInstance(SetpriceCommand.class));
commands.add(injector.getInstance(SetownerCommand.class));
commands.add(injector.getInstance(SetdurationCommand.class));
commands.add(injector.getInstance(SetTransferCommand.class));
commands.add(injector.getInstance(ReloadCommand.class));
commands.add(injector.getInstance(GroupaddCommand.class));
commands.add(injector.getInstance(GroupdelCommand.class));
@@ -2,6 +2,8 @@ package me.wiefferink.areashop.managers;
import com.google.inject.Injector;
import com.google.inject.ProvisionException;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.CommandsFeature;
import me.wiefferink.areashop.features.DebugFeature;
@@ -14,8 +16,6 @@ import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.regions.GeneralRegion;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
@@ -1,16 +1,19 @@
package me.wiefferink.areashop.managers;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import io.github.bakedlibs.dough.blocks.BlockPosition;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
import me.wiefferink.areashop.events.notify.AddedRegionEvent;
import me.wiefferink.areashop.events.notify.DeletedRegionEvent;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -32,8 +35,6 @@ import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -43,6 +44,7 @@ import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -52,11 +54,12 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Singleton
public class FileManager extends Manager {
public class FileManager extends Manager implements IFileManager {
private final AreaShop plugin;
private final Map<String, GeneralRegion> regions;
@@ -77,29 +80,12 @@ public class FileManager extends Manager {
private HashMap<String, Integer> versions = null;
private final String versionPath;
private final String schemFolder;
private final SignManager signManager;
private final WorldGuardInterface worldGuardInterface;
private final MessageBridge messageBridge;
private final RegionFactory regionFactory;
// Enum for region types
public enum AddResult {
BLACKLISTED("blacklisted"),
NOPERMISSION("nopermission"),
ALREADYADDED("alreadyadded"),
ALREADYADDEDOTHERWORLD("alreadyaddedotherworld"),
SUCCESS("success");
private final String value;
AddResult(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
/**
* Constructor, initialize variabeles.
*/
@@ -108,12 +94,14 @@ public class FileManager extends Manager {
@Nonnull AreaShop plugin,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull MessageBridge messageBridge,
@Nonnull RegionFactory regionFactory
@Nonnull RegionFactory regionFactory,
@Nonnull SignManager signManager
) {
this.plugin = plugin;
this.worldGuardInterface = worldGuardInterface;
this.messageBridge = messageBridge;
this.regionFactory = regionFactory;
this.signManager = signManager;
regions = new HashMap<>();
buys = new HashMap<>();
rents = new HashMap<>();
@@ -136,7 +124,11 @@ public class FileManager extends Manager {
public void shutdown() {
// Update lastactive time for players that are online now
for(GeneralRegion region : this.regions.values()) {
Player player = Bukkit.getPlayer(region.getOwner());
UUID ownerUuid = region.getOwner();
if (ownerUuid == null) {
continue;
}
Player player = Bukkit.getPlayer(ownerUuid);
if(player != null) {
region.updateLastActiveTime();
}
@@ -154,6 +146,7 @@ public class FileManager extends Manager {
* Get the folder where schematics are stored.
* @return The folder where schematics are stored
*/
@Override
public String getSchematicFolder() {
return schemFolder;
}
@@ -163,6 +156,7 @@ public class FileManager extends Manager {
* @param name The name of the group to get (will be normalized)
* @return The group if found, otherwise null
*/
@Override
public RegionGroup getGroup(String name) {
return groups.get(name.toLowerCase());
}
@@ -171,6 +165,7 @@ public class FileManager extends Manager {
* Get all groups.
* @return Collection with all groups (safe to modify)
*/
@Override
public Collection<RegionGroup> getGroups() {
return groups.values();
}
@@ -179,6 +174,7 @@ public class FileManager extends Manager {
* Get the default region settings as provided by the user (default.yml).
* @return YamlConfiguration with the settings (might miss settings, which should be filled in with {@link #getFallbackRegionSettings()})
*/
@Override
public YamlConfiguration getRegionSettings() {
return defaultConfig;
}
@@ -187,6 +183,7 @@ public class FileManager extends Manager {
* Get the default regions settings as provided by AreaShop (default.yml).
* @return YamlConfiguration with the default settings
*/
@Override
public YamlConfiguration getFallbackRegionSettings() {
return defaultConfigFallback;
}
@@ -195,6 +192,7 @@ public class FileManager extends Manager {
* Get the config file (config.yml).
* @return YamlConfiguration with the settings of users, with fallback to the settings provided by AreaShop
*/
@Override
public YamlConfiguration getConfig() {
return config;
}
@@ -204,6 +202,7 @@ public class FileManager extends Manager {
* @param name The name of the region to get (will be normalized)
* @return The region if found, otherwise null
*/
@Override
public @Nullable GeneralRegion getRegion(String name) {
return regions.get(name.toLowerCase());
}
@@ -213,6 +212,7 @@ public class FileManager extends Manager {
* @param name The name of the rental region (will be normalized)
* @return RentRegion if it could be found, otherwise null
*/
@Override
public @Nullable RentRegion getRent(String name) {
return rents.get(name.toLowerCase(Locale.ENGLISH));
}
@@ -222,6 +222,7 @@ public class FileManager extends Manager {
* @param name The name of the buy region (will be normalized)
* @return BuyRegion if it could be found, otherwise null
*/
@Override
public @Nullable BuyRegion getBuy(String name) {
return buys.get(name.toLowerCase(Locale.ENGLISH));
}
@@ -230,6 +231,7 @@ public class FileManager extends Manager {
* Get all rental regions.
* @return List of all rental regions
*/
@Override
public Collection<RentRegion> getRents() {
return new ArrayList<>(rents.values());
}
@@ -238,6 +240,7 @@ public class FileManager extends Manager {
* Get all rental regions.
* @return List of all rental regions
*/
@Override
public Collection<RentRegion> getRentsRef() {
return Collections.unmodifiableCollection(rents.values());
}
@@ -246,10 +249,12 @@ public class FileManager extends Manager {
* Get all buy regions.
* @return List of all buy regions
*/
@Override
public List<BuyRegion> getBuys() {
return new ArrayList<>(buys.values());
}
@Override
public Collection<BuyRegion> getBuysRef() {
return Collections.unmodifiableCollection(buys.values());
}
@@ -259,6 +264,7 @@ public class FileManager extends Manager {
* Get all regions.
* @return List of all regions (it is safe to modify the list)
*/
@Override
public List<GeneralRegion> getRegions() {
return new ArrayList<>(regions.values());
}
@@ -267,6 +273,7 @@ public class FileManager extends Manager {
* Get all regions.
* @return List of all regions (it is safe to modify the list)
*/
@Override
public Collection<GeneralRegion> getRegionsRef() {
return Collections.unmodifiableCollection(regions.values());
}
@@ -275,6 +282,7 @@ public class FileManager extends Manager {
* Get a list of names of all buy regions.
* @return A String list with all the names
*/
@Override
public List<String> getBuyNames() {
ArrayList<String> result = new ArrayList<>(buys.size());
for(BuyRegion region : buys.values()) {
@@ -287,6 +295,7 @@ public class FileManager extends Manager {
* Get a list of names of all rent regions.
* @return A String list with all the names
*/
@Override
public List<String> getRentNames() {
ArrayList<String> result = new ArrayList<>(rents.size());
for(RentRegion region : rents.values()) {
@@ -299,6 +308,7 @@ public class FileManager extends Manager {
* Get a list of names of all regions.
* @return A String list with all the names
*/
@Override
public List<String> getRegionNames() {
ArrayList<String> result = new ArrayList<>(regions.size());
for(GeneralRegion region : regions.values()) {
@@ -311,6 +321,7 @@ public class FileManager extends Manager {
* Get a list of names of all groups.
* @return A String list with all the names
*/
@Override
public List<String> getGroupNames() {
ArrayList<String> result = new ArrayList<>();
for(RegionGroup group : groups.values()) {
@@ -324,6 +335,7 @@ public class FileManager extends Manager {
* @param region Then region to add
* @return true when successful, otherwise false (denied by an event listener)
*/
@Override
public AddingRegionEvent addRegion(GeneralRegion region) {
AddingRegionEvent event = addRegionNoSave(region);
if (event.isCancelled()) {
@@ -339,6 +351,7 @@ public class FileManager extends Manager {
* @param region The region to add
* @return true when successful, otherwise false (denied by an event listener)
*/
@Override
public AddingRegionEvent addRegionNoSave(GeneralRegion region) {
AddingRegionEvent event = new AddingRegionEvent(region);
if(region == null) {
@@ -352,10 +365,10 @@ public class FileManager extends Manager {
}
final String key = region.getName().toLowerCase(Locale.ENGLISH);
regions.put(key, region);
if (region instanceof BuyRegion) {
buys.put(key, (BuyRegion) region);
} else if (region instanceof RentRegion) {
rents.put(key, (RentRegion) region);
if (region instanceof BuyRegion buyRegion) {
buys.put(key, buyRegion);
} else if (region instanceof RentRegion rentRegion) {
rents.put(key, rentRegion);
}
Bukkit.getPluginManager().callEvent(new AddedRegionEvent(region));
return event;
@@ -364,6 +377,7 @@ public class FileManager extends Manager {
/**
* Mark all RegionGroups that they should regenerate regions.
*/
@Override
public void markGroupsAutoDirty() {
for(RegionGroup group : getGroups()) {
group.autoDirty();
@@ -374,6 +388,7 @@ public class FileManager extends Manager {
* Add a RegionGroup.
* @param group The RegionGroup to add
*/
@Override
public void addGroup(RegionGroup group) {
groups.put(group.getName().toLowerCase(), group);
String lowGroup = group.getName().toLowerCase();
@@ -390,7 +405,11 @@ public class FileManager extends Manager {
* @param type The type the region should have in AreaShop
* @return The result if a player would want to add this region
*/
public AddResult checkRegionAdd(CommandSender sender, ProtectedRegion region, World world, RegionType type) {
@Override
public AddResult checkRegionAdd(CommandSender sender,
ProtectedRegion region,
World world,
RegionType type) {
Player player = null;
if(sender instanceof Player) {
player = (Player)sender;
@@ -432,6 +451,7 @@ public class FileManager extends Manager {
* @param giveMoneyBack use true to give money back to the player if someone is currently holding this region, otherwise false
* @return true if the region has been removed, false otherwise
*/
@Override
public DeletingRegionEvent deleteRegion(GeneralRegion region, boolean giveMoneyBack) {
DeletingRegionEvent event = new DeletingRegionEvent(region);
if(region == null) {
@@ -456,8 +476,11 @@ public class FileManager extends Manager {
// Delete the signs
if(region.getWorld() != null) {
for(BlockPosition sign : region.getSignsFeature().signManager().allSignLocations()) {
SignManager regionSignManager = region.getSignsFeature().signManager();
for(BlockPosition sign : regionSignManager.allSignLocations()) {
sign.getBlock().setType(Material.AIR);
regionSignManager.removeSign(sign);
this.signManager.removeSign(sign);
}
}
@@ -496,6 +519,7 @@ public class FileManager extends Manager {
* Remove a group.
* @param group Group to remove
*/
@Override
public void removeGroup(RegionGroup group) {
groups.remove(group.getLowerCaseName());
groupsConfig.set(group.getLowerCaseName(), null);
@@ -505,6 +529,7 @@ public class FileManager extends Manager {
/**
* Update all signs that need periodic updating.
*/
@Override
public void performPeriodicSignUpdate() {
Do.forAll(
plugin.getConfig().getInt("signs.regionsPerTick"),
@@ -520,6 +545,7 @@ public class FileManager extends Manager {
/**
* Send out rent expire warnings.
*/
@Override
public void sendRentExpireWarnings() {
Do.forAll(
plugin.getConfig().getInt("expireWarning.regionsPerTick"),
@@ -533,7 +559,9 @@ public class FileManager extends Manager {
* @param regions Regions to update
* @param confirmationReceiver The CommandSender that should be notified at completion
*/
public void updateRegions(final Collection<GeneralRegion> regions, final CommandSender confirmationReceiver) {
@Override
public void updateRegions(final Collection<GeneralRegion> regions,
final CommandSender confirmationReceiver) {
final int regionsPerTick = plugin.getConfig().getInt("update.regionsPerTick");
if(confirmationReceiver != null) {
messageBridge.message(confirmationReceiver, "reload-updateStart", regions.size(), regionsPerTick * 20);
@@ -554,6 +582,7 @@ public class FileManager extends Manager {
* Update a list of regions.
* @param regions The list of regions to update.
*/
@Override
public void updateRegions(Collection<GeneralRegion> regions) {
updateRegions(regions, null);
}
@@ -561,6 +590,7 @@ public class FileManager extends Manager {
/**
* Update all regions, happens in a task to minimize lag.
*/
@Override
public void updateAllRegions() {
updateRegions(getRegionsRef(), null);
}
@@ -569,6 +599,7 @@ public class FileManager extends Manager {
* Update all regions.
* @param confirmationReceiver Optional CommandSender that should receive progress messages
*/
@Override
public void updateAllRegions(CommandSender confirmationReceiver) {
updateRegions(getRegionsRef(), confirmationReceiver);
}
@@ -577,6 +608,7 @@ public class FileManager extends Manager {
/**
* Save the group file to disk.
*/
@Override
public void saveGroupsIsRequired() {
saveGroupsRequired = true;
}
@@ -585,6 +617,7 @@ public class FileManager extends Manager {
* Check if saving the groups file is required.
* @return true if changes are made and saving is required, otherwise false
*/
@Override
public boolean isSaveGroupsRequired() {
return saveGroupsRequired;
}
@@ -592,6 +625,7 @@ public class FileManager extends Manager {
/**
* Save the groups file to disk synchronously.
*/
@Override
public void saveGroupsNow() {
AreaShop.debug("saveGroupsNow() done");
saveGroupsRequired = false;
@@ -606,6 +640,7 @@ public class FileManager extends Manager {
/**
* Save all region related files spread over time (low load).
*/
@Override
public void saveRequiredFiles() {
if(isSaveGroupsRequired()) {
saveGroupsNow();
@@ -626,6 +661,7 @@ public class FileManager extends Manager {
/**
* Save all region related files directly (only for cases like onDisable()).
*/
@Override
public void saveRequiredFilesAtOnce() {
if(isSaveGroupsRequired()) {
saveGroupsNow();
@@ -642,6 +678,7 @@ public class FileManager extends Manager {
* Indicates that a/multiple WorldGuard regions need to be saved.
* @param worldName The world where the regions that should be saved is in
*/
@Override
public void saveIsRequiredForRegionWorld(String worldName) {
worldRegionsRequireSaving.add(worldName);
}
@@ -649,6 +686,7 @@ public class FileManager extends Manager {
/**
* Save all worldGuard regions that need saving.
*/
@Override
public void saveWorldGuardRegions() {
for(String world : worldRegionsRequireSaving) {
World bukkitWorld = Bukkit.getWorld(world);
@@ -669,6 +707,7 @@ public class FileManager extends Manager {
* Get the folder the region files are located in.
* @return The folder where the region.yml files are in
*/
@Override
public String getRegionFolder() {
return regionsPath;
}
@@ -678,6 +717,7 @@ public class FileManager extends Manager {
* @param region The region name to check
* @return true if the region may not be added, otherwise false
*/
@Override
public boolean isBlacklisted(String region) {
for(String line : plugin.getConfig().getStringList("blacklist")) {
Pattern pattern = Pattern.compile(line, Pattern.CASE_INSENSITIVE);
@@ -692,6 +732,7 @@ public class FileManager extends Manager {
/**
* Unrent regions that have no time left, regions to check per tick is in the config.
*/
@Override
public void checkRents() {
Do.forAll(
plugin.getConfig().getInt("expiration.regionsPerTick"),
@@ -703,6 +744,7 @@ public class FileManager extends Manager {
/**
* Check all regions and unrent/sell them if the player is inactive for too long.
*/
@Override
public void checkForInactiveRegions() {
Do.forAll(
plugin.getConfig().getInt("inactive.regionsPerTick"),
@@ -715,6 +757,7 @@ public class FileManager extends Manager {
/**
* Load the file with the versions, used to check if the other files need conversion.
*/
@Override
@SuppressWarnings("unchecked")
public void loadVersions() {
File file = new File(versionPath);
@@ -737,6 +780,7 @@ public class FileManager extends Manager {
/**
* Save the versions file to disk.
*/
@Override
public void saveVersions() {
if(!(new File(versionPath).exists())) {
AreaShop.debug("versions file created, this should happen only after installing or upgrading the plugin");
@@ -753,6 +797,7 @@ public class FileManager extends Manager {
* @param thisTick Load files in the current tick or a tick later
* @return true if the files are loaded correctly, otherwise false
*/
@Override
public boolean loadFiles(boolean thisTick) {
// Load config.yml + add defaults from .jar
boolean result = loadConfigFile();
@@ -784,6 +829,7 @@ public class FileManager extends Manager {
* Load the default.yml file
* @return true if it has been loaded successfully, otherwise false
*/
@Override
public boolean loadDefaultFile() {
boolean result = true;
File defaultFile = new File(defaultPath);
@@ -805,8 +851,8 @@ public class FileManager extends Manager {
}
// Load default.yml from the plugin folder, and as backup the default one
try(
InputStreamReader custom = new InputStreamReader(new FileInputStream(defaultFile), Charsets.UTF_8);
InputStreamReader normal = new InputStreamReader(plugin.getResource(AreaShop.defaultFile), Charsets.UTF_8)
InputStreamReader custom = new InputStreamReader(new FileInputStream(defaultFile), StandardCharsets.UTF_8);
InputStreamReader normal = new InputStreamReader(plugin.getResource(AreaShop.defaultFile), StandardCharsets.UTF_8)
) {
defaultConfig = YamlConfiguration.loadConfiguration(custom);
if(defaultConfig.getKeys(false).isEmpty()) {
@@ -824,6 +870,7 @@ public class FileManager extends Manager {
* Load the default.yml file
* @return true if it has been loaded successfully, otherwise false
*/
@Override
public boolean loadConfigFile() {
boolean result = true;
File configFile = new File(configPath);
@@ -845,9 +892,9 @@ public class FileManager extends Manager {
}
// Load config.yml from the plugin folder
try(
InputStreamReader custom = new InputStreamReader(new FileInputStream(configFile), Charsets.UTF_8);
InputStreamReader normal = new InputStreamReader(plugin.getResource(AreaShop.configFile), Charsets.UTF_8);
InputStreamReader hidden = new InputStreamReader(plugin.getResource(AreaShop.configFileHidden), Charsets.UTF_8)
InputStreamReader custom = new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8);
InputStreamReader normal = new InputStreamReader(plugin.getResource(AreaShop.configFile), StandardCharsets.UTF_8);
InputStreamReader hidden = new InputStreamReader(plugin.getResource(AreaShop.configFileHidden), StandardCharsets.UTF_8)
) {
config = YamlConfiguration.loadConfiguration(custom);
if(config.getKeys(false).isEmpty()) {
@@ -878,12 +925,13 @@ public class FileManager extends Manager {
* Load the groups.yml file from disk
* @return true if succeeded, otherwise false
*/
@Override
public boolean loadGroupsFile() {
boolean result = true;
File groupFile = new File(groupsPath);
if(groupFile.exists() && groupFile.isFile()) {
try(
InputStreamReader reader = new InputStreamReader(new FileInputStream(groupFile), Charsets.UTF_8)
InputStreamReader reader = new InputStreamReader(new FileInputStream(groupFile), StandardCharsets.UTF_8)
) {
groupsConfig = YamlConfiguration.loadConfiguration(reader);
} catch(IOException e) {
@@ -903,8 +951,11 @@ public class FileManager extends Manager {
/**
* Load all region files.
*/
@Override
public void loadRegionFiles() {
regions.clear();
this.regions.clear();
this.buys.clear();
this.rents.clear();
final File file = new File(regionsPath);
if(!file.exists()) {
if(!file.mkdirs()) {
@@ -928,7 +979,7 @@ public class FileManager extends Manager {
List<String> noRegionType = new ArrayList<>();
List<String> noNamePaths = new ArrayList<>();
List<GeneralRegion> noWorld = new ArrayList<>();
List<GeneralRegion> noRegion = new ArrayList<>();
Map<GeneralRegion, File> noRegion = new HashMap<>();
List<GeneralRegion> incorrectDuration = new ArrayList<>();
for(File regionFile : regionFiles) {
if(regionFile.exists() && regionFile.isFile() && !regionFile.isHidden()) {
@@ -936,11 +987,13 @@ public class FileManager extends Manager {
// Load the region file from disk in UTF8 mode
YamlConfiguration regionConfig;
try(
InputStreamReader reader = new InputStreamReader(new FileInputStream(regionFile), Charsets.UTF_8)
InputStreamReader reader = new InputStreamReader(new FileInputStream(regionFile), StandardCharsets.UTF_8)
) {
regionConfig = YamlConfiguration.loadConfiguration(reader);
if(regionConfig.getKeys(false).isEmpty()) {
AreaShop.warn("Region file '" + regionFile.getName() + "' is empty, check for errors in the log.");
regionFile.delete();
continue;
}
} catch(IOException e) {
AreaShop.warn("Something went wrong reading region file: " + regionFile.getAbsolutePath());
@@ -966,7 +1019,7 @@ public class FileManager extends Manager {
} else if(region.getWorld() == null) {
noWorld.add(region);
} else if(region.getRegion() == null) {
noRegion.add(region);
noRegion.put(region, regionFile);
} else if(region instanceof RentRegion && !Utils.checkTimeFormat(((RentRegion)region).getDurationString())) {
incorrectDuration.add(region);
} else {
@@ -990,11 +1043,11 @@ public class FileManager extends Manager {
if(!noRegion.isEmpty()) {
List<String> noRegionNames = new ArrayList<>();
for(GeneralRegion region : noRegion) {
noRegionNames.add(region.getName());
for(Map.Entry<GeneralRegion, File> regionMap : noRegion.entrySet()) {
noRegionNames.add(regionMap.getKey().getName());
regionMap.getValue().delete();
}
AreaShop.warn("AreaShop regions that are missing their WorldGuard region: " + Utils.createCommaSeparatedList(noRegionNames));
AreaShop.warn("Remove these regions from AreaShop with '/as del' or recreate their regions in WorldGuard.");
AreaShop.warn("AreaShop regions that are missing their WorldGuard region are now being deleted: " + Utils.createCommaSeparatedList(noRegionNames));
}
boolean noWorldRegions = !noWorld.isEmpty();
@@ -1345,6 +1398,7 @@ public class FileManager extends Manager {
* @param groupName Name of the group to get the settings from
* @return The settings of the group
*/
@Override
public ConfigurationSection getGroupSettings(String groupName) {
return groupsConfig.getConfigurationSection(groupName.toLowerCase());
}
@@ -1355,6 +1409,7 @@ public class FileManager extends Manager {
* @param path The path to set
* @param setting The value to set
*/
@Override
public void setGroupSetting(RegionGroup group, String path, Object setting) {
groupsConfig.set(group.getName().toLowerCase() + "." + path, setting);
}
@@ -0,0 +1,399 @@
package me.wiefferink.areashop.managers;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
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.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
public interface IFileManager {
/**
* Get the folder where schematics are stored.
*
* @return The folder where schematics are stored
*/
String getSchematicFolder();
/**
* Get a group.
*
* @param name The name of the group to get (will be normalized)
* @return The group if found, otherwise null
*/
RegionGroup getGroup(String name);
/**
* Get all groups.
*
* @return Collection with all groups (safe to modify)
*/
Collection<RegionGroup> getGroups();
/**
* Get the default region settings as provided by the user (default.yml).
*
* @return YamlConfiguration with the settings (might miss settings, which should be filled in with {@link #getFallbackRegionSettings()})
*/
YamlConfiguration getRegionSettings();
/**
* Get the default regions settings as provided by AreaShop (default.yml).
*
* @return YamlConfiguration with the default settings
*/
YamlConfiguration getFallbackRegionSettings();
/**
* Get the config file (config.yml).
*
* @return YamlConfiguration with the settings of users, with fallback to the settings provided by AreaShop
*/
YamlConfiguration getConfig();
/**
* Get a region.
*
* @param name The name of the region to get (will be normalized)
* @return The region if found, otherwise null
*/
@Nullable
GeneralRegion getRegion(String name);
/**
* Get a rental region.
*
* @param name The name of the rental region (will be normalized)
* @return RentRegion if it could be found, otherwise null
*/
@Nullable
RentRegion getRent(String name);
/**
* Get a buy region.
*
* @param name The name of the buy region (will be normalized)
* @return BuyRegion if it could be found, otherwise null
*/
@Nullable
BuyRegion getBuy(String name);
/**
* Get all rental regions.
*
* @return List of all rental regions
*/
Collection<RentRegion> getRents();
/**
* Get all rental regions (readonly)
*
* @return Unmodifiable collection of all rental regions
*/
Collection<RentRegion> getRentsRef();
/**
* Get all buy regions.
*
* @return List of all buy regions
*/
List<BuyRegion> getBuys();
/**
* Get all buy regions (readonly)
* @return Unmodifiable collection of all buy regions
*/
Collection<BuyRegion> getBuysRef();
/**
* Get all regions.
*
* @return List of all regions (it is safe to modify the list)
*/
List<GeneralRegion> getRegions();
/**
* Get all regions (readonly)
*
* @return Unmodifiable collection of all regions
*/
Collection<GeneralRegion> getRegionsRef();
/**
* Get a list of names of all buy regions.
*
* @return A String list with all the names
*/
List<String> getBuyNames();
/**
* Get a list of names of all rent regions.
*
* @return A String list with all the names
*/
List<String> getRentNames();
/**
* Get a list of names of all regions.
*
* @return A String list with all the names
*/
List<String> getRegionNames();
/**
* Get a list of names of all groups.
*
* @return A String list with all the names
*/
List<String> getGroupNames();
/**
* Add a region to the list and mark it as to-be-saved.
*
* @param region Then region to add
* @return true when successful, otherwise false (denied by an event listener)
*/
AddingRegionEvent addRegion(GeneralRegion region);
/**
* Add a region to the list without saving it to disk (useful for loading at startup).
*
* @param region The region to add
* @return true when successful, otherwise false (denied by an event listener)
*/
AddingRegionEvent addRegionNoSave(GeneralRegion region);
/**
* Mark all RegionGroups that they should regenerate regions.
*/
void markGroupsAutoDirty();
/**
* Add a RegionGroup.
*
* @param group The RegionGroup to add
*/
void addGroup(RegionGroup group);
/**
* Check if a player can add a certain region as rent or buy region.
*
* @param sender The player/console that wants to add a region
* @param region The WorldGuard region to add
* @param world The world the ProtectedRegion is located in
* @param type The type the region should have in AreaShop
* @return The result if a player would want to add this region
*/
AddResult checkRegionAdd(CommandSender sender,
ProtectedRegion region,
World world,
GeneralRegion.RegionType type);
/**
* Remove a region from the list.
*
* @param region The region to remove
* @param giveMoneyBack use true to give money back to the player if someone is currently holding this region, otherwise false
* @return true if the region has been removed, false otherwise
*/
DeletingRegionEvent deleteRegion(GeneralRegion region, boolean giveMoneyBack);
/**
* Remove a group.
*
* @param group Group to remove
*/
void removeGroup(RegionGroup group);
/**
* Update all signs that need periodic updating.
*/
void performPeriodicSignUpdate();
/**
* Send out rent expire warnings.
*/
void sendRentExpireWarnings();
/**
* Update regions in a task to minimize lag.
*
* @param regions Regions to update
* @param confirmationReceiver The CommandSender that should be notified at completion
*/
void updateRegions(Collection<GeneralRegion> regions, CommandSender confirmationReceiver);
/**
* Update a list of regions.
*
* @param regions The list of regions to update.
*/
void updateRegions(Collection<GeneralRegion> regions);
/**
* Update all regions, happens in a task to minimize lag.
*/
void updateAllRegions();
/**
* Update all regions.
*
* @param confirmationReceiver Optional CommandSender that should receive progress messages
*/
void updateAllRegions(CommandSender confirmationReceiver);
/**
* Save the group file to disk.
*/
void saveGroupsIsRequired();
/**
* Check if saving the groups file is required.
*
* @return true if changes are made and saving is required, otherwise false
*/
boolean isSaveGroupsRequired();
/**
* Save the groups file to disk synchronously.
*/
void saveGroupsNow();
/**
* Save all region related files spread over time (low load).
*/
void saveRequiredFiles();
/**
* Save all region related files directly (only for cases like onDisable()).
*/
void saveRequiredFilesAtOnce();
/**
* Indicates that a/multiple WorldGuard regions need to be saved.
*
* @param worldName The world where the regions that should be saved is in
*/
void saveIsRequiredForRegionWorld(String worldName);
/**
* Save all worldGuard regions that need saving.
*/
void saveWorldGuardRegions();
/**
* Get the folder the region files are located in.
*
* @return The folder where the region.yml files are in
*/
String getRegionFolder();
/**
* Check if a region is on the adding blacklist.
*
* @param region The region name to check
* @return true if the region may not be added, otherwise false
*/
boolean isBlacklisted(String region);
/**
* Unrent regions that have no time left, regions to check per tick is in the config.
*/
void checkRents();
/**
* Check all regions and unrent/sell them if the player is inactive for too long.
*/
void checkForInactiveRegions();
/**
* Load the file with the versions, used to check if the other files need conversion.
*/
@SuppressWarnings("unchecked")
void loadVersions();
/**
* Save the versions file to disk.
*/
void saveVersions();
/**
* Load all files from disk.
*
* @param thisTick Load files in the current tick or a tick later
* @return true if the files are loaded correctly, otherwise false
*/
boolean loadFiles(boolean thisTick);
/**
* Load the default.yml file
*
* @return true if it has been loaded successfully, otherwise false
*/
boolean loadDefaultFile();
/**
* Load the default.yml file
*
* @return true if it has been loaded successfully, otherwise false
*/
boolean loadConfigFile();
/**
* Load the groups.yml file from disk
*
* @return true if succeeded, otherwise false
*/
boolean loadGroupsFile();
/**
* Load all region files.
*/
void loadRegionFiles();
/**
* Get the settings of a group.
*
* @param groupName Name of the group to get the settings from
* @return The settings of the group
*/
ConfigurationSection getGroupSettings(String groupName);
/**
* Set a setting for a group.
*
* @param group The group to set it for
* @param path The path to set
* @param setting The value to set
*/
void setGroupSetting(RegionGroup group, String path, Object setting);
// Enum for region types
public enum AddResult {
BLACKLISTED("blacklisted"),
NOPERMISSION("nopermission"),
ALREADYADDED("alreadyadded"),
ALREADYADDEDOTHERWORLD("alreadyaddedotherworld"),
SUCCESS("success");
private final String value;
AddResult(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
@@ -1,12 +1,14 @@
package me.wiefferink.areashop.managers;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.SignUtils;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -23,8 +25,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.util.BlockIterator;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -41,8 +41,6 @@ public class SignLinkerManager extends Manager implements Listener {
@Inject
private AreaShop plugin;
@Inject
private BukkitInterface bukkitInterface;
@Inject
private SignManager signManager;
@Inject
private MessageBridge messageBridge;
@@ -147,7 +145,7 @@ public class SignLinkerManager extends Manager implements Listener {
messageBridge.message(player, "linksigns-alreadyRegistered", regionSign.getRegion());
return;
}
linker.setSign(block.getLocation(), block.getType(), bukkitInterface.getSignFacing(block));
linker.setSign(block.getLocation(), block.getType(), SignUtils.getSignFacing(block));
}
}
}
@@ -6,68 +6,64 @@ import com.google.inject.assistedinject.FactoryModuleBuilder;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.features.FeatureFactory;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.features.signs.SignsModule;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.CommandManager;
import me.wiefferink.areashop.managers.FeatureManager;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
import me.wiefferink.areashop.nms.NMS;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.regions.ImportJobFactory;
import me.wiefferink.areashop.regions.RegionModule;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nonnull;
import java.util.Arrays;
public class AreaShopModule extends AbstractModule {
private final AreaShop instance;
private final BukkitInterface bukkitInterface;
private final WorldGuardInterface worldGuardInterface;
private final WorldEditInterface worldEditInterface;
private final NMS nms;
private final PlatformAdapter platformAdapter;
private final MessageBridge messageBridge;
private final SignErrorLogger signErrorLogger;
private final DependencyModule dependencyModule;
private final AbstractModule[] extras;
public AreaShopModule(@Nonnull AreaShop instance,
@Nonnull MessageBridge messageBridge,
@Nonnull NMS nms,
@Nonnull BukkitInterface bukkitInterface,
@Nonnull PlatformAdapter platformAdapter,
@Nonnull WorldEditInterface worldEditInterface,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull SignErrorLogger signErrorLogger,
@Nonnull DependencyModule dependencyModule
@Nonnull AbstractModule... extras
) {
this.instance = instance;
this.messageBridge = messageBridge;
this.nms = nms;
this.platformAdapter = platformAdapter;
this.signErrorLogger = signErrorLogger;
this.bukkitInterface = bukkitInterface;
this.worldEditInterface = worldEditInterface;
this.worldGuardInterface = worldGuardInterface;
this.dependencyModule = dependencyModule;
this.extras = extras;
}
@Override
protected void configure() {
install(this.dependencyModule);
Arrays.stream(this.extras).forEach(this::install);
bind(Plugin.class).toInstance(this.instance);
bind(AreaShop.class).toInstance(this.instance);
bind(MessageBridge.class).toInstance(this.messageBridge);
bind(NMS.class).toInstance(this.nms);
bind(BlockBehaviourHelper.class).toInstance(this.nms.blockBehaviourHelper());
bind(BukkitInterface.class).toInstance(this.bukkitInterface);
bind(WorldGuardInterface.class).toInstance(this.worldGuardInterface);
bind(SignManager.class).asEagerSingleton();
bind(WorldEditInterface.class).toInstance(this.worldEditInterface);
bind(SignErrorLogger.class).toInstance(this.signErrorLogger);
// Setup managers
bind(FileManager.class).asEagerSingleton();
bind(IFileManager.class).to(FileManager.class).asEagerSingleton();
bind(FeatureManager.class).in(Singleton.class);
bind(CommandManager.class).in(Singleton.class);
bind(SignLinkerManager.class).in(Singleton.class);
@@ -0,0 +1,29 @@
package me.wiefferink.areashop.modules;
import com.google.inject.AbstractModule;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.jetbrains.annotations.NotNull;
public class PlatformModule extends AbstractModule {
private final MinecraftPlatform minecraftPlatform;
private final PlatformAdapter platformAdapter;
public PlatformModule(@NotNull MinecraftPlatform platform,
@NotNull PlatformAdapter platformAdapter) {
this.minecraftPlatform = platform;
this.platformAdapter = platformAdapter;
}
@Override
protected void configure() {
bind(MinecraftPlatform.class).toInstance(this.minecraftPlatform);
bind(OfflinePlayerHelper.class).toInstance(this.minecraftPlatform.offlinePlayerHelper());
bind(PlatformAdapter.class).toInstance(this.platformAdapter);
bind(BlockBehaviourHelper.class).toInstance(this.platformAdapter.blockBehaviourHelper());
bind(BukkitSchedulerExecutor.class).asEagerSingleton();
}
}
@@ -58,6 +58,21 @@ public class BuyRegion extends GeneralRegion {
this.economy = economy;
}
@Override
public boolean isOwner(UUID player) {
return isBuyer(player);
}
@Override
public UUID getOwner() {
return getBuyer();
}
@Override
public void setOwner(UUID player) {
setBuyer(player);
}
@Override
public RegionType getType() {
return RegionType.BUY;
@@ -237,31 +252,20 @@ public class BuyRegion extends GeneralRegion {
@Override
public Object provideReplacement(String variable) {
switch(variable) {
case AreaShop.tagPrice:
return getFormattedPrice();
case AreaShop.tagRawPrice:
return getPrice();
case AreaShop.tagPlayerName:
return getPlayerName();
case AreaShop.tagPlayerUUID:
return getBuyer();
case AreaShop.tagResellPrice:
return getFormattedResellPrice();
case AreaShop.tagRawResellPrice:
return getResellPrice();
case AreaShop.tagMoneyBackAmount:
return getFormattedMoneyBackAmount();
case AreaShop.tagRawMoneyBackAmount:
return getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage:
return getMoneyBackPercentage() % 1.0 == 0.0 ? (int)getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagMaxInactiveTime:
return this.getFormattedInactiveTimeUntilSell();
default:
return super.provideReplacement(variable);
}
return switch (variable) {
case AreaShop.tagPrice -> getFormattedPrice();
case AreaShop.tagRawPrice -> getPrice();
case AreaShop.tagPlayerName -> getPlayerName();
case AreaShop.tagPlayerUUID -> getBuyer();
case AreaShop.tagResellPrice -> getFormattedResellPrice();
case AreaShop.tagRawResellPrice -> getResellPrice();
case AreaShop.tagMoneyBackAmount -> getFormattedMoneyBackAmount();
case AreaShop.tagRawMoneyBackAmount -> getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage ->
getMoneyBackPercentage() % 1.0 == 0.0 ? (int) getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagMaxInactiveTime -> this.getFormattedInactiveTimeUntilSell();
default -> super.provideReplacement(variable);
};
}
/**
@@ -404,8 +408,6 @@ public class BuyRegion extends GeneralRegion {
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());
@@ -417,6 +419,9 @@ public class BuyRegion extends GeneralRegion {
// Notify about updates
this.notifyAndUpdate(new ResoldRegionEvent(this, oldOwner));
// Resell is done, disable that now
disableReselling();
// Send message to the player
message(offlinePlayer, "buy-successResale", oldOwnerName);
Player seller = Bukkit.getPlayer(oldOwner);
@@ -479,7 +484,7 @@ public class BuyRegion extends GeneralRegion {
*/
@SuppressWarnings("deprecation")
public boolean sell(boolean giveMoneyBack, CommandSender executor) {
boolean own = executor instanceof Player && this.isBuyer((Player)executor);
boolean own = executor instanceof Player player && this.isBuyer(player);
if(executor != null) {
if(!executor.hasPermission("areashop.sell") && !own) {
message(executor, "sell-noPermissionOther");
@@ -534,7 +539,7 @@ public class BuyRegion extends GeneralRegion {
// Give back the money
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
if(player != null && !noPayBack) {
if(player.hasPlayedBefore() && !noPayBack) {
EconomyResponse response = null;
boolean error = false;
try {
@@ -13,7 +13,7 @@ import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FeatureManager;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import me.wiefferink.interactivemessenger.processing.Message;
@@ -31,6 +31,7 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import javax.annotation.Nonnull;
import java.awt.geom.Area;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
@@ -42,9 +43,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public abstract class GeneralRegion implements GeneralRegionInterface, Comparable<GeneralRegion>, ReplacementProvider {
@@ -415,7 +418,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
* Get the FileManager from the plugin.
* @return The FileManager (responsible for saving/loading regions and getting them)
*/
public FileManager getFileManager() {
public IFileManager getFileManager() {
return plugin.getFileManager();
}
@@ -433,33 +436,18 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
* @param player Player to check ownership for
* @return true if the player currently rents or buys this region
*/
public boolean isOwner(UUID player) {
return (this instanceof RentRegion && ((RentRegion)this).isRenter(player)) || (this instanceof BuyRegion && ((BuyRegion)this).isBuyer(player));
}
public abstract boolean isOwner(UUID player);
/**
* Get the player that is currently the owner of this region (either bought or rented it).
* @return The UUID of the owner of this region
*/
public UUID getOwner() {
if(this instanceof RentRegion) {
return ((RentRegion)this).getRenter();
} else {
return ((BuyRegion)this).getBuyer();
}
}
public abstract UUID getOwner();
/**
* Change the owner of the region.
* @param player The player that should be the owner
*/
public void setOwner(UUID player) {
if(this instanceof RentRegion) {
((RentRegion)this).setRenter(player);
} else {
((BuyRegion)this).setBuyer(player);
}
}
public abstract void setOwner(UUID player);
/**
* Get the landlord of this region (the player that receives any revenue from this region).
@@ -478,7 +466,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
if(landlordName != null && !landlordName.isEmpty()) {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(landlordName);
if(offlinePlayer != null) {
if(offlinePlayer.hasPlayedBefore()) {
return offlinePlayer.getUniqueId();
}
}
@@ -491,7 +479,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
*/
public String getLandlordName() {
String result = Utils.toName(getLandlord());
if(result == null || result.isEmpty()) {
if(result.isEmpty()) {
result = config.getString("general.landlordName");
if(result == null || result.isEmpty()) {
result = null;
@@ -510,7 +498,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
setSetting("general.landlord", landlord.toString());
}
String properName = Utils.toName(landlord);
if(properName == null) {
if(properName.isBlank()) {
properName = name;
}
setSetting("general.landlordName", properName);
@@ -530,7 +518,8 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
* @return true if the player is the landlord, otherwise false
*/
public boolean isLandlord(UUID landlord) {
return landlord != null && getLandlord() != null && getLandlord().equals(landlord);
UUID ourLandlord = getLandlord();
return Objects.equals(landlord, ourLandlord);
}
/**
@@ -628,86 +617,96 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
@Override
public Object provideReplacement(String variable) {
switch(variable) {
switch (variable) {
// Basics
case AreaShop.tagRegionName:
case AreaShop.tagRegionName -> {
return getName();
case AreaShop.tagRegionType:
}
case AreaShop.tagRegionType -> {
return getType().getValue().toLowerCase();
case AreaShop.tagWorldName:
}
case AreaShop.tagWorldName -> {
return getWorldName();
case AreaShop.tagWidth:
}
case AreaShop.tagWidth -> {
return getWidth();
case AreaShop.tagDepth:
}
case AreaShop.tagDepth -> {
return getDepth();
case AreaShop.tagHeight:
}
case AreaShop.tagHeight -> {
return getHeight();
case AreaShop.tagFriends:
}
case AreaShop.tagFriends -> {
return Utils.createCommaSeparatedList(getFriendsFeature().getFriendNames());
case AreaShop.tagFriendsUUID:
}
case AreaShop.tagFriendsUUID -> {
return Utils.createCommaSeparatedList(getFriendsFeature().getFriends());
case AreaShop.tagLandlord:
}
case AreaShop.tagLandlord -> {
return getLandlordName();
case AreaShop.tagLandlordUUID:
}
case AreaShop.tagLandlordUUID -> {
return getLandlord();
case AreaShop.tagVolume:
}
case AreaShop.tagVolume -> {
return getVolume();
}
// Date/time
case AreaShop.tagEpoch:
case AreaShop.tagEpoch -> {
return Calendar.getInstance().getTimeInMillis();
case AreaShop.tagMillisecond:
}
case AreaShop.tagMillisecond -> {
return Calendar.getInstance().get(Calendar.MILLISECOND);
case AreaShop.tagSecond:
}
case AreaShop.tagSecond -> {
return Calendar.getInstance().get(Calendar.SECOND);
case AreaShop.tagMinute:
}
case AreaShop.tagMinute -> {
return Calendar.getInstance().get(Calendar.MINUTE);
case AreaShop.tagHour:
}
case AreaShop.tagHour -> {
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
case AreaShop.tagDay:
}
case AreaShop.tagDay -> {
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
case AreaShop.tagMonth:
}
case AreaShop.tagMonth -> {
return Calendar.getInstance().get(Calendar.MONTH) + 1;
case AreaShop.tagYear:
}
case AreaShop.tagYear -> {
return Calendar.getInstance().get(Calendar.YEAR);
case AreaShop.tagDateTime:
}
case AreaShop.tagDateTime -> {
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")).format(Calendar.getInstance().getTime());
case AreaShop.tagDateTimeShort:
}
case AreaShop.tagDateTimeShort -> {
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")).format(Calendar.getInstance().getTime());
}
// Teleport locations
default:
default -> {
Location tp = getTeleportFeature().getTeleportLocation();
if(tp == null) {
if (tp == null) {
return null;
}
switch(variable) {
case AreaShop.tagTeleportBlockX:
return tp.getBlockX();
case AreaShop.tagTeleportBlockY:
return tp.getBlockY();
case AreaShop.tagTeleportBlockZ:
return tp.getBlockZ();
case AreaShop.tagTeleportX:
return tp.getX();
case AreaShop.tagTeleportY:
return tp.getY();
case AreaShop.tagTeleportZ:
return tp.getZ();
case AreaShop.tagTeleportPitch:
return tp.getPitch();
case AreaShop.tagTeleportYaw:
return tp.getYaw();
case AreaShop.tagTeleportPitchRound:
return Math.round(tp.getPitch());
case AreaShop.tagTeleportYawRound:
return Math.round(tp.getYaw());
case AreaShop.tagTeleportWorld:
return tp.getWorld().getName();
default:
return null;
}
return switch (variable) {
case AreaShop.tagTeleportBlockX -> tp.getBlockX();
case AreaShop.tagTeleportBlockY -> tp.getBlockY();
case AreaShop.tagTeleportBlockZ -> tp.getBlockZ();
case AreaShop.tagTeleportX -> tp.getX();
case AreaShop.tagTeleportY -> tp.getY();
case AreaShop.tagTeleportZ -> tp.getZ();
case AreaShop.tagTeleportPitch -> tp.getPitch();
case AreaShop.tagTeleportYaw -> tp.getYaw();
case AreaShop.tagTeleportPitchRound -> Math.round(tp.getPitch());
case AreaShop.tagTeleportYawRound -> Math.round(tp.getYaw());
case AreaShop.tagTeleportWorld -> tp.getWorld().getName();
default -> null;
};
}
}
}
@@ -796,11 +795,9 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
File saveFile = new File(plugin.getFileManager().getSchematicFolder() + File.separator + fileName);
// Create parent directories
File parent = saveFile.getParentFile();
if(parent != null && !parent.exists()) {
if(!parent.mkdirs()) {
AreaShop.warn("Did not save region " + getName() + ", schematic directory could not be created: " + saveFile.getAbsolutePath());
return false;
}
if(parent != null && !parent.exists() && !parent.mkdirs()) {
AreaShop.warn("Did not save region " + getName() + ", schematic directory could not be created: " + saveFile.getAbsolutePath());
return false;
}
boolean result = worldEditInterface.saveRegionBlocks(saveFile, this);
if(result) {
@@ -809,6 +806,38 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
return true;
}
/**
* Save all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
* @return true if the region has been saved properly, otherwise false
*/
public CompletableFuture<Boolean> saveRegionBlocksAsync(String fileName) {
if (!worldEditInterface.supportsAsyncOperations()) {
return CompletableFuture.completedFuture(saveRegionBlocks(fileName));
}
// Check if the region is correct
ProtectedRegion region = getRegion();
if(region == null) {
AreaShop.debug("Region '" + getName() + "' does not exist in WorldGuard, save failed");
return CompletableFuture.completedFuture(false);
}
// The path to save the schematic
File saveFile = new File(plugin.getFileManager().getSchematicFolder() + File.separator + fileName);
// Create parent directories
File parent = saveFile.getParentFile();
if(parent != null && !parent.exists() && !parent.mkdirs()) {
AreaShop.warn("Did not save region " + getName() + ", schematic directory could not be created: " + saveFile.getAbsolutePath());
return CompletableFuture.completedFuture(false);
}
return worldEditInterface.saveRegionBlocksAsync(saveFile, this)
.thenApply(result -> {
if(Boolean.TRUE.equals(result)) {
AreaShop.debug("Saved schematic async for region " + getName());
}
return result;
});
}
/**
* Restore all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
@@ -831,6 +860,35 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
return result;
}
/**
* Restore all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
* @return true if the region has been restored properly, otherwise false
*/
public CompletableFuture<Boolean> restoreRegionBlocksAsync(String fileName) {
if (!worldEditInterface.supportsAsyncOperations()) {
return CompletableFuture.completedFuture(restoreRegionBlocks(fileName));
}
if(getRegion() == null) {
AreaShop.debug("Region '" + getName() + "' does not exist in WorldGuard, restore failed");
return CompletableFuture.completedFuture(false);
}
// The path to save the schematic
File restoreFile = new File(plugin.getFileManager().getSchematicFolder() + File.separator + fileName);
return worldEditInterface.restoreRegionBlocksAsync(restoreFile, this)
.thenApply(result -> {
if(Boolean.TRUE.equals(result)) {
AreaShop.debug("Restored schematic async for region " + getName());
// Sync back to main
Do.syncLater(10, getSignsFeature().signManager()::update);
}
return result;
}
);
}
/**
* Reset all flags of the region.
*/
@@ -910,7 +968,6 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
if(found) {
return result;
}
if(this.getFileManager().getRegionSettings().isString(path)) {
return this.getFileManager().getRegionSettings().getString(path).equalsIgnoreCase("true");
}
@@ -1419,8 +1476,8 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
public boolean matchesLimitGroup(String group) {
List<String> worlds = plugin.getConfig().getStringList("limitGroups." + group + ".worlds");
List<String> groups = plugin.getConfig().getStringList("limitGroups." + group + ".groups");
if((worlds == null || worlds.isEmpty() || worlds.contains(getWorldName()))) {
if(groups == null || groups.isEmpty()) {
if(worlds.isEmpty() || worlds.contains(getWorldName())) {
if(groups.isEmpty()) {
return true;
} else {
boolean inGroups = false;
@@ -1452,14 +1509,23 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
String save = profileSection.getString(type.getValue() + ".save");
String restore = profileSection.getString(type.getValue() + ".restore");
// Save the region if needed
if(save != null && !save.isEmpty()) {
boolean async = worldEditInterface.supportsAsyncOperations();
if(save != null && !save.isBlank()) {
save = Message.fromString(save).replacements(this).getSingle();
saveRegionBlocks(save);
if (async) {
saveRegionBlocksAsync(save);
} else {
saveRegionBlocks(save);
}
}
// Restore the region if needed
if(restore != null && !restore.isEmpty()) {
if(restore != null && !restore.isBlank()) {
restore = Message.fromString(restore).replacements(this).getSingle();
restoreRegionBlocks(restore);
if (async) {
restoreRegionBlocksAsync(restore);
} else {
restoreRegionBlocks(restore);
}
}
}
@@ -1523,6 +1589,22 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
return volume;
}
/**
* Whether region transfers are enabled
* @return Returns true if region transfers are enabled, false otherwise
*/
public boolean isTransferEnabled() {
return getBooleanSetting("general.transferMode");
}
/**
* Se whether region transfers are enabled
* @param enabled Whether region transfers should be enabled, false otherwise
*/
public void setTransferEnabled(boolean enabled) {
setSetting("general.transferMode", enabled);
}
/**
* Calculate the volume of the region (could be expensive for polygon regions).
* @return Number of blocks in the region
@@ -11,7 +11,7 @@ import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
@@ -34,7 +34,7 @@ import java.util.UUID;
public class ImportJob {
private final AreaShop plugin;
private final FileManager fileManager;
private final IFileManager fileManager;
private final SignManager signManager;
private final WorldGuardInterface worldGuardInterface;
private final CommandSender sender;
@@ -48,7 +48,7 @@ public class ImportJob {
@AssistedInject
ImportJob(
@Nonnull AreaShop plugin,
@Nonnull FileManager fileManager,
@Nonnull IFileManager fileManager,
@Nonnull SignManager signManager,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull MessageBridge messageBridge,
@@ -393,8 +393,7 @@ public class ImportJob {
// Set rented until
if(from.isLong("info.last-withdrawal")
&& region instanceof RentRegion) {
RentRegion rentRegion = (RentRegion)region;
&& region instanceof RentRegion rentRegion) {
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());
@@ -445,7 +444,7 @@ public class ImportJob {
}
}
private static final List<TimeUnit> timeUnitLookup = new ArrayList<TimeUnit>() {
private static final List<TimeUnit> timeUnitLookup = new ArrayList<>() {
{
add(new TimeUnit(60 * 24 * 30 * 12, "year"));
add(new TimeUnit(60 * 24 * 30, "month"));
@@ -2,7 +2,7 @@ package me.wiefferink.areashop.regions;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
@@ -16,7 +16,7 @@ import java.util.Set;
public class RegionGroup {
private final Plugin plugin;
private final FileManager fileManager;
private final IFileManager fileManager;
private final String name;
private final Set<String> regions;
private Set<String> autoRegions;
@@ -29,7 +29,7 @@ public class RegionGroup {
* @param name Name of the group, has to be unique
*/
@AssistedInject
RegionGroup(@Nonnull Plugin plugin, @Nonnull FileManager fileManager, @Assisted String name) {
RegionGroup(@Nonnull Plugin plugin, @Nonnull IFileManager fileManager, @Assisted String name) {
this.plugin = plugin;
this.fileManager = fileManager;
this.name = name;
@@ -72,6 +72,22 @@ public class RentRegion extends GeneralRegion {
this.economy = economy;
}
@Override
public boolean isOwner(UUID player) {
return isRenter(player);
}
@Override
public UUID getOwner() {
return getRenter();
}
@Override
public void setOwner(UUID player) {
setRenter(player);
}
@Override
public RegionType getType() {
return RegionType.RENT;
@@ -165,43 +181,28 @@ public class RentRegion extends GeneralRegion {
@Override
public Object provideReplacement(String variable) {
switch(variable) {
case AreaShop.tagPrice:
return getFormattedPrice();
case AreaShop.tagRawPrice:
return getPrice();
case AreaShop.tagDuration:
return getDurationString();
case AreaShop.tagPlayerName:
return getPlayerName();
case AreaShop.tagPlayerUUID:
return getRenter();
case AreaShop.tagRentedUntil:
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")).format(new Date(getRentedUntil()));
case AreaShop.tagRentedUntilShort:
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")).format(new Date(getRentedUntil()));
case AreaShop.tagTimeLeft:
return getTimeLeftString();
case AreaShop.tagMoneyBackAmount:
return getFormattedMoneyBackAmount();
case AreaShop.tagRawMoneyBackAmount:
return getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage:
return (getMoneyBackPercentage() % 1.0) == 0.0 ? (int)getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagTimesExtended:
return this.getTimesExtended();
case AreaShop.tagMaxExtends:
return this.getMaxExtends();
case AreaShop.tagExtendsLeft:
return getMaxExtends() - getTimesExtended();
case AreaShop.tagMaxRentTime:
return millisToHumanFormat(getMaxRentTime());
case AreaShop.tagMaxInactiveTime:
return this.getFormattedInactiveTimeUntilUnrent();
default:
return super.provideReplacement(variable);
}
return switch (variable) {
case AreaShop.tagPrice -> getFormattedPrice();
case AreaShop.tagRawPrice -> getPrice();
case AreaShop.tagDuration -> getDurationString();
case AreaShop.tagPlayerName -> getPlayerName();
case AreaShop.tagPlayerUUID -> getRenter();
case AreaShop.tagRentedUntil ->
new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")).format(new Date(getRentedUntil()));
case AreaShop.tagRentedUntilShort ->
new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")).format(new Date(getRentedUntil()));
case AreaShop.tagTimeLeft -> getTimeLeftString();
case AreaShop.tagMoneyBackAmount -> getFormattedMoneyBackAmount();
case AreaShop.tagRawMoneyBackAmount -> getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage ->
(getMoneyBackPercentage() % 1.0) == 0.0 ? (int) getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagTimesExtended -> this.getTimesExtended();
case AreaShop.tagMaxExtends -> this.getMaxExtends();
case AreaShop.tagExtendsLeft -> getMaxExtends() - getTimesExtended();
case AreaShop.tagMaxRentTime -> millisToHumanFormat(getMaxRentTime());
case AreaShop.tagMaxInactiveTime -> this.getFormattedInactiveTimeUntilUnrent();
default -> super.provideReplacement(variable);
};
}
/**
@@ -672,10 +673,10 @@ public class RentRegion extends GeneralRegion {
}
// Broadcast and check event
UnrentingRegionEvent event = new UnrentingRegionEvent(this);
Bukkit.getPluginManager().callEvent(event);
if(event.isCancelled()) {
message(executor, "general-cancelled", event.getReason());
UnrentingRegionEvent unrentingRegionEvent = new UnrentingRegionEvent(this);
Bukkit.getPluginManager().callEvent(unrentingRegionEvent);
if(unrentingRegionEvent.isCancelled()) {
message(executor, "general-cancelled", unrentingRegionEvent.getReason());
return false;
}
@@ -729,13 +730,17 @@ public class RentRegion extends GeneralRegion {
// Remove friends, the owner and renteduntil values
getFriendsFeature().clearFriends();
UUID oldRenter = getRenter();
setRenter(null);
setRentedUntil(null);
setTimesExtended(-1);
removeLastActiveTime();
// Notify about updates
this.notifyAndUpdate(new UnrentedRegionEvent(this, oldRenter, Math.max(0, moneyBack)));
Bukkit.getPluginManager().callEvent(new UnrentedRegionEvent(this, oldRenter, Math.max(0, moneyBack)));
// Placed here so when event is passed, the player renting can still be accessed
setRenter(null);
// Update world (has to be after setting renter to null)
this.update();
return true;
}
@@ -0,0 +1,26 @@
package me.wiefferink.areashop.tools;
import jakarta.inject.Inject;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Executor;
public class BukkitSchedulerExecutor implements Executor {
private final Plugin plugin;
private final BukkitScheduler scheduler;
@Inject
public BukkitSchedulerExecutor(@NotNull Plugin plugin, @NotNull BukkitScheduler scheduler) {
this.plugin = plugin;
this.scheduler = scheduler;
}
@Override
public void execute(@NotNull Runnable command) {
this.scheduler.runTask(this.plugin, command);
}
}
@@ -20,7 +20,7 @@ public class GithubUpdateCheck {
public static final String API_HOST = "https://api.github.com/repos";
public static final String API_LATEST_RELEASE = "releases/latest";
public static final String USER_AGENT = "GithubUpdateCheck by NLThijs48";
public static final String USER_AGENT = "md5sha256 AreaShop GithubUpdateCheck";
public static final boolean DEBUG = false;
private final String author;
@@ -0,0 +1,97 @@
package me.wiefferink.areashop.tools;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
/**
* Sign Utilities class
*/
public final class SignUtils {
private SignUtils() {
}
/**
* Get the {@link BlockFace} of a sign block
* If the passed {@link Block} is not an instance of either
* a {@link Sign} or {@link WallSign}, this method will return <code>null</code>
*
* @param block The sign
* @return Returns the {@link BlockFace} of the sign or <code>null</code>
*/
public static BlockFace getSignFacing(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if (blockData instanceof WallSign wallSign) {
return wallSign.getFacing();
} else if (blockData instanceof org.bukkit.block.data.type.Sign sign) {
return sign.getRotation();
}
return null;
}
/**
* Set the {@link BlockFace} in which the sign will face
* If the passed {@link Block} is not an instance of either
* a {@link Sign} or {@link WallSign}, this method will return <code>null</code>.
*
* @param block The sign block
* @param facing The new {@link BlockFace} the sign should face
* @return Returns <code>true</code> if the sign was successfully placed, <code>false</code> otherwise
*/
public static boolean setSignFacing(Block block, BlockFace facing) {
if (block == null || facing == null) {
return false;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if (blockData instanceof WallSign wallSign) {
wallSign.setFacing(facing);
} else if (blockData instanceof org.bukkit.block.data.type.Sign sign) {
sign.setRotation(facing);
} else {
return false;
}
block.setBlockData(blockData);
return true;
}
/**
* Get the {@link Block} which a given sign is attached to.
* This method will return <code>null</code> if the passed {@link Block}
* is not an instance of either a {@link Sign} or {@link WallSign}.
*
* @param block The sign {@link Block}
* @return Returns the block which the sign is attached to or null
*/
public static Block getSignAttachedTo(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if (blockData instanceof WallSign wallSign) {
return block.getRelative(wallSign.getFacing().getOppositeFace());
} else if (blockData instanceof Sign) {
return block.getRelative(BlockFace.DOWN);
}
return null;
}
}
@@ -0,0 +1,42 @@
package me.wiefferink.areashop.tools;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class SpigotOfflinePlayerHelper implements OfflinePlayerHelper {
private final Plugin plugin;
public SpigotOfflinePlayerHelper(@NotNull Plugin plugin) {
this.plugin = plugin;
}
@Override
public CompletableFuture<Optional<UUID>> lookupUuidAsync(String username) {
return lookupOfflinePlayerAsync(username).thenApply(player -> {
if (player.hasPlayedBefore()) {
return Optional.of(player.getUniqueId());
}
return Optional.empty();
});
}
@Override
public CompletableFuture<OfflinePlayer> lookupOfflinePlayerAsync(String username) {
final CompletableFuture<OfflinePlayer> future = new CompletableFuture<>();
final Server server = this.plugin.getServer();
server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
@SuppressWarnings("deprecation")
OfflinePlayer player = server.getOfflinePlayer(username);
future.complete(player);
});
return future;
}
}
@@ -0,0 +1,20 @@
package me.wiefferink.areashop.tools;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public class SpigotPlatform implements MinecraftPlatform {
private final OfflinePlayerHelper offlinePlayerHelper;
public SpigotPlatform(@NotNull Plugin plugin) {
this.offlinePlayerHelper = new SpigotOfflinePlayerHelper(plugin);
}
@Override
public OfflinePlayerHelper offlinePlayerHelper() {
return this.offlinePlayerHelper;
}
}
@@ -2,6 +2,7 @@ package me.wiefferink.areashop.tools;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import jakarta.inject.Inject;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
@@ -23,7 +24,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import javax.inject.Inject;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
@@ -0,0 +1,40 @@
package me.wiefferink.areashop.tools.version;
import javax.annotation.Nullable;
import java.util.Locale;
public enum PreReleaseType {
UNKNOWN("unknown"),
ALPHA("alpha"),
BETA("beta"),
SNAPSHOT("snapshot"),
RELEASE_CANDIDATE("rc");
private static final PreReleaseType[] VALUES = values();
private final String asString;
PreReleaseType(String asString) {
this.asString = asString;
}
@Nullable
public static PreReleaseType parse(String release) {
if (release.isEmpty()) {
return null;
}
String sanitized = release.toLowerCase(Locale.ENGLISH);
for (PreReleaseType preReleaseType : VALUES) {
if (preReleaseType.asString.equals(sanitized)) {
return preReleaseType;
}
}
return UNKNOWN;
}
public String asString() {
return this.asString;
}
}
@@ -0,0 +1,54 @@
package me.wiefferink.areashop.tools.version;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public record Version(String original, VersionData versionData) {
/**
* Semver pattern, cg1 = major, cg2 = minor, cg3 = patch, cg4 = prerelease and cg5 = buildmetadata
* Taken from https://semver.org/ and https://regex101.com/r/vkijKf/1/
*/
public static final Pattern SEMVER_PATTERN = Pattern.compile(
"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
public static Version parse(String version) {
Matcher matcher = SEMVER_PATTERN.matcher(version);
if (!matcher.find()) {
throw new IllegalArgumentException("Invalid version: " + version);
}
String majorRaw = matcher.group(1);
String minorRaw = matcher.group(2);
String patchRaw = matcher.group(3);
String preReleaseRaw = matcher.group(4);
int major;
int minor;
try {
major = Integer.parseInt(majorRaw);
minor = Integer.parseInt(minorRaw);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid version: " + version);
}
if (patchRaw == null || patchRaw.isEmpty()) {
return new Version(version, new VersionData(major, minor, 0, null));
}
int patch;
try {
patch = Integer.parseInt(patchRaw);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid version: " + version);
}
if (preReleaseRaw == null || preReleaseRaw.isEmpty()) {
return new Version(version, new VersionData(major, minor, patch, null));
}
PreReleaseType releaseType = PreReleaseType.parse(preReleaseRaw);
return new Version(version, new VersionData(major, minor, patch, releaseType));
}
@Override
public String toString() {
return this.original;
}
}
@@ -0,0 +1,54 @@
package me.wiefferink.areashop.tools.version;
import org.jetbrains.annotations.NotNull;
public record VersionData(int major, int minor, int patch, PreReleaseType preReleaseType)
implements Comparable<VersionData> {
public VersionData(int major, int minor, int patch) {
this(major, minor, patch, null);
}
public VersionData(int major, int minor) {
this(major, minor, 0);
}
@Override
public String toString() {
return String.format("%d.%d.%d", major, minor, patch);
}
public boolean isNewerThan(VersionData other) {
return compareTo(other) > 0;
}
public boolean isOlderThan(VersionData other) {
return compareTo(other) < 0;
}
@Override
public int compareTo(@NotNull VersionData o) {
int majorComp = Integer.compare(this.major, o.major);
if (majorComp != 0) {
return majorComp;
}
int minorComp = Integer.compare(this.minor, o.minor);
if (minorComp != 0) {
return minorComp;
}
int patchComp = Integer.compare(this.patch, o.patch);
if (patchComp != 0) {
return patchComp;
}
if (this.preReleaseType == null && o.preReleaseType == null) {
return 0;
}
if (this.preReleaseType == null) {
return 1;
}
return this.preReleaseType.compareTo(o.preReleaseType);
}
}
@@ -0,0 +1,22 @@
package me.wiefferink.areashop.tools.version;
public class VersionUtil {
public static VersionData MC_1_17_1 = new VersionData(1, 17, 1);
public static Version parseMinecraftVersion(String minecraftVersion) {
// Expecting 1.X.X-R0.1-SNAPSHOT
int stripLength = "-R0.1-SNAPSHOT".length();
int length = minecraftVersion.length();
if (length <= stripLength) {
throw new IllegalArgumentException("Invalid minecraft version: " + minecraftVersion);
}
String strippedVersion = minecraftVersion.substring(0, length - stripLength);
try {
return Version.parse(strippedVersion);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Invalid minecraft version: " + minecraftVersion, ex);
}
}
}
+4
View File
@@ -121,6 +121,10 @@ debug: false
version: ${project.version}
# Maximum number of blocks to save to or restore from a .schemetic file.
maximumBlocks: 1000000
# Whether to forcefully clear "hanging" entities (painting, itemframes, etc.) on region restore
# Only enable this option if hanging entities at the destination aren't removed on restore normally
# If set to true, there may be a performance impact when performing region restores.
forceClearEntities: false
# Maximum number of locations the teleport function should check to find a safe spot.
maximumTries: 50000
+2
View File
@@ -34,6 +34,8 @@ general:
landlordName: ''
# Disable to prevent counting this region towards limits set by 'limitGroups' in config.yml.
countForLimits: true
# Whether transferring tenant <--> tenant and landlord <--> landlord should be enabled
transferMode: false
##### Set the layout and functions of the signs.
# The following sections can be added for performing certain commands when the sign is clicked:
+20 -3
View File
@@ -80,6 +80,7 @@ help-reload: "%lang:helpCommand|/as reload|% Reload all files and update the reg
help-setrestore: "%lang:helpCommand|/as setrestore|% Set restoring on/off and choose profile."
help-setprice: "%lang:helpCommand|/as setprice|% Change the price of a region."
help-setduration: "%lang:helpCommand|/as setduration|% Change the duration of a rent region."
help-settransfer: "%lang:helpCommand|/as settransfer|% Set transfer on/off."
help-teleport: "%lang:helpCommand|/as tp|% Teleport to a rent/buy region."
help-setteleport: "%lang:helpCommand|/as settp|% Set teleport position for a region."
help-find: "%lang:helpCommand|/as find|% Find an empty buy or rent."
@@ -102,6 +103,7 @@ help-linksigns: "%lang:helpCommand|/as linksigns|% Use bulk sign linking mode."
help-stack: "%lang:helpCommand|/as stack|% Create multiple regions and add them."
help-setlandlord: "%lang:helpCommand|/as setlandlord|% Set the landlord of a region."
help-import: "%lang:helpCommand|/as import|% Import region from RegionForSale."
help-transfer: "%lang:helpCommand|/as transfer|% Transfer a region to another player."
rent-help: "/as rent [region], the region you stand in will be used if not specified."
rent-noPermission: "You don't have permission to rent a region."
@@ -156,6 +158,15 @@ sell-noPermission: "You don't have permission to sell a region."
sell-noPermissionOther: "You don't have permission to sell another region."
sell-disabled: "Selling has been disabled for this region."
transfer-help: "/as transfer <player> [region], the region you stand in will be used if not specified."
transfer-noPermission: "You don't have permission to transfer a region."
transfer-disabled: "Transferring has been disabled for this region."
transfer-transferred-owner: "%lang:region% has been transferred and is now owned by %0%."
transfer-transferred-tenant: "%lang:region% has been transferred and is now occupied by %0%."
transfer-noPlayer: "Unknown player: %0%"
transfer-notCurrentTenant: "You are not the current tenant of this region."
transfer-transferSelf: "You cannot transfer a region to yourself."
reload-reloading: "Reloaded all configuration and region files."
reload-updateStart: ""
reload-updateComplete: ""
@@ -303,6 +314,12 @@ setrestore-invalidSetting: "'%0%' is not a valid state, should be true, false or
setrestore-success: "Successfully set the restore setting of %lang:region% to '%0%'."
setrestore-successProfile: "Successfully set the restore setting of %lang:region% to '%0%' and the profile to '%1%'."
settransfer-help: "/as settransfer <region> <true|false>."
settransfer-noPermission: "You don't have permission to change the transfer settings."
settransfer-notRegistered: "The specified region is not registered: %0%."
settransfer-invalidSetting: "'%0%' is not a valid state, should be true, false or general."
settransfer-success: "Successfully set the transfer setting of %lang:region% to '%0%'."
setprice-noPermission: "You don't have permission to change the price of a region."
setprice-help: "/as setprice <price> [region], the region you stand in will be used if not specified."
setprice-notRegistered: "The specified region is not registered: %0%."
@@ -619,7 +636,7 @@ greeting-resale: "%region% can be bought for %resellprice% from %player%."
update-playerNotify:
- "[darkgreen]Update from AreaShop V%0% to AreaShop V%1% available, get the latest version at "
- "[bold]Spigot[/bold]"
- " hover: %lang:action|Go to the Spigot AreaShop page|%"
- " link: https://www.spigotmc.org/resources/areashop.2991/"
- "[bold]Github[/bold]"
- " hover: %lang:action|Go to the AreaShop Github Releases|%"
- " link: https://github.com/md5sha256/releases"
- " (and leave a review)."
+3 -3
View File
@@ -1,11 +1,11 @@
name: AreaShop
main: me.wiefferink.areashop.AreaShop
version: "@version@"
version: "${version}"
description: "Selling and renting WorldGuard regions to your players, highly configurable."
depend: [Vault, WorldGuard, WorldEdit]
softdepend: [Multiverse-Core, FastAsyncWorldEdit]
author: NLThijs48
website: https://github.com/NLthijs48/AreaShop
website: https://github.com/md5sha256/AreaShop
commands:
AreaShop:
description: 'For all commands use /as help.'
@@ -13,7 +13,7 @@ commands:
aliases: [as]
awareness:
- !@UTF8
api-version: 1.13
api-version: 1.17
permissions:
areashop.*:
description: Give access to all commands of AreaShop
+21 -32
View File
@@ -1,6 +1,8 @@
![AreaShop logo](https://cloud.githubusercontent.com/assets/6951068/9471294/f016d8ee-4b4f-11e5-9bda-d61b1c423ebb.png)<br/>
[![](https://jitpack.io/v/md5sha256/AreaShop.svg)](https://jitpack.io/#md5sha256/AreaShop)
<br>
**Usage and configuration:**
[►Download (releases)](https://github.com/NLthijs48/AreaShop/releases)&nbsp;&nbsp;
[►Download (releases)](https://github.com/md5sha256/AreasShop/releases)&nbsp;&nbsp;
[►Commands and Permissions](https://github.com/NLthijs48/AreaShop/wiki/Commands-and-Permissions)
<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
[►Basic regions setup](https://github.com/NLthijs48/AreaShop/wiki/Basic-regions-setup)&nbsp;&nbsp;
@@ -14,11 +16,10 @@
[►Frequently Asked Questions](https://github.com/NLthijs48/AreaShop/wiki/Frequently-Asked-Questions)&nbsp;&nbsp;
[►Common errors](https://github.com/NLthijs48/AreaShop/wiki/Common-errors)<br/>
**Support:**
[►Request a feature, report a bug or ask support](https://github.com/NLthijs48/AreaShop/issues/new/choose)&nbsp;&nbsp;
[►Open issues](https://github.com/NLthijs48/AreaShop/issues)<br/>
[►Request a feature, report a bug or ask support](https://github.com/md5sha256/AreasShop/issues/new/choose)&nbsp;&nbsp;
[►Open issues](https://github.com/md5sha256/AreasShop/issues)<br/>
**Development:**
[►Changelog](https://github.com/NLthijs48/AreaShop/blob/master/changelog.md)&nbsp;&nbsp;
[►Compiling](https://github.com/NLthijs48/AreaShop/wiki/Compiling-AreaShop)&nbsp;&nbsp;
[►Compiling](https://github.com/md5sha256/AreaShop/tree/dev/bleeding/documentation/compiling.md)&nbsp;&nbsp;
[►Modules/classes overview](https://github.com/NLthijs48/AreaShop/wiki/Modules,-packages-and-classes-overview)
[►Javadocs](https://wiefferink.me/AreaShop/javadocs/)
[►Development builds](http://jenkins.wiefferink.me/job/AreaShop)<br/>
@@ -26,7 +27,19 @@
[►AreaShop in Spigot Resources](http://www.spigotmc.org/resources/areashop.2991/)&nbsp;&nbsp;
[►AreaShop on BukkitDev](http://dev.bukkit.org/bukkit-plugins/regionbuyandrent/)
***
### Required dependencies
* Java 17 or higher (latest recommended)
* Bukkit/Spigot 1.17.2 or newer (hybrids such as Mohist are not supported)
* [WorldGuard](http://dev.bukkit.org/bukkit-plugins/worldguard/): 7.0.7 or newer
* [WorldEdit](http://dev.bukkit.org/bukkit-plugins/worldedit/): 7.2.12 or newer
* [Vault](http://dev.bukkit.org/bukkit-plugins/vault/): 1.7.3 or higher
* An economy plugin supported by Vault (check the [Vault page](http://dev.bukkit.org/bukkit-plugins/vault/) for a list of these)
### Optional Dependencies
* [FastAsyncWorldEdit](https://www.spigotmc.org/resources/fastasyncworldedit.13932/) 2.4.5 or newer (Note: Use either FAWE or WE, not both together)
* AreaShop has a separate adapter for FAWE which leverages its support for asynchronous edit operations. This adapter is used for region saving and restoring.
* Note that schematics created by the FAWE adapter are not compatible with normal WorldEdit; however, schematics created by the normal WorldEdit adapter are compatible with FAWE
* Due to a bug with FAWE, entities are not saved by the FAWE adapter but are saved in the normal WE adapter
AreaShop allows you selling and renting regions to players. It could be used to let them rent a jail in your prison server, a shop in the market of the survival server or a plot on a creative server. The player interacts with signs, making it easy to use. It also has a lot of commands to check the status of all regions, manage the renting and buying of a region and also features for admins. A lot of messages send to the player can be clicked, for immediately performing actions (buying the region, selling the region, etc.) or getting more information (for example clicking region name for region information). To setup the renting and selling of the regions exactly as you want AreaShop has a lot of options to custimize it to your liking.
@@ -36,7 +49,7 @@ AreaShop allows you selling and renting regions to players. It could be used to
* ![rented-sign](https://cloud.githubusercontent.com/assets/6951068/21939029/3844896a-d9be-11e6-8492-7a23ec71fce2.png)
* Messages that can be clicked for more information and actions ([language](https://github.com/NLthijs48/AreaShop/wiki/Language-support) can be changed, as well as click/hover actions).
* ![region-information-message](https://cloud.githubusercontent.com/assets/6951068/21939161/bff2fe3c-d9be-11e6-802f-4a0bce073c64.png)
* Change the of the plugin or use of of the already provided language files (check [here](https://github.com/NLthijs48/AreaShop/tree/master/AreaShop/src/main/resources/lang))
* Change the of the plugin or use of the already provided language files (check [here](https://github.com/md5sha256/AreasShop/tree/dev/bleeding/AreaShop/src/main/resources/lang))
* Automatically restore the region to its original state when sold: [restore](https://github.com/NLthijs48/AreaShop/wiki/Region-blocks-save-restore) the region with schematics.
* Change which [commands](https://github.com/NLthijs48/AreaShop/wiki/Commands-and-Permissions) players can use with [permissions](https://github.com/NLthijs48/AreaShop/wiki/Commands-and-Permissions).
* Customize the plugin by changing the [config files](https://github.com/NLthijs48/AreaShop/wiki/The-config-system).
@@ -61,28 +74,4 @@ For a preview join 'mc.go-craft.com' and go to the Survival server, the shops ar
**Made by [PerkulatorTime](https://www.youtube.com/user/PerkulatorTime)**<br/>
[![Tutorial Video](https://cloud.githubusercontent.com/assets/6951068/9532788/147526cc-4d0e-11e5-9672-1274faae280a.png)](https://www.youtube.com/watch?v=OQOsOG-EdNc)
Old video for AreaShop v1.0: [Tutorial by VariationVault](https://www.youtube.com/watch?v=k2HMCxCCOYo)
### Required dependencies
* Java 7 or higher (latest recommended)
* Bukkit/Spigot 1.7.9 or higher (modded servers often include Bukkit/Spigot support, so it should also work on that, but it is not specifically tested for it)
* [WorldGuard](http://dev.bukkit.org/bukkit-plugins/worldguard/): 5.9 or higher (6.0+ recommended)
* [WorldEdit](http://dev.bukkit.org/bukkit-plugins/worldedit/): 5.6.3 or higher (6.0+ recommended)
* [Vault](http://dev.bukkit.org/bukkit-plugins/vault/): 1.4.1 or higher
* An economy plugin supported by Vault (check the [Vault page](http://dev.bukkit.org/bukkit-plugins/vault/) for a list of these)
### Metrics
This plugin utilizes Hidendra's plugin metrics system, which means that the following information is collected and sent to mcstats.org:
*A unique identifier, the server's version of Java, whether the server is in offline or online mode, the plugin's version, the server's version, the OS version/name and architecture, the core count for the CPU, the number of players online, the Metrics version.*
This information will give me an indication how much the plugin is used and encourages me to continue development. Opting out of this service can be done by setting `sendStats` in the config of this plugin to `false`, if you want to disable Metrics for any plugin go to `plugins/Plugin Metrics/config.yml` and change `opt-out` to `true`. Check graphs of the statistics at this page: [mcstats.org/plugin/AreaShop](http://mcstats.org/plugin/AreaShop)
### Do you want to translate AreaShop?
Help translating the plugin into different languages and to keep the translations up to date. Go to [this page](https://github.com/NLthijs48/AreaShop/wiki/Language-support#translating-on-transifex) for more information. Translating goes through the [Transifex](https://www.transifex.com/projects/p/areashop/) website and is very easy, sending files back and forth is not needed, you can translate lines online and whenever you want. Every line you translate will be saved, no need to do it all at once (this also allows for easy collaboration).
![Transifex-translation-progress](https://transifex.com/projects/p/areashop/resource/enyml/chart/image_png)
[![Discord-support-chat](https://discordapp.com/api/v6/guilds/342592311122853893/widget.png?style=banner3)](https://discord.gg/84kGMCQ)
[![Donate through PayPal to support development](https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VEECV88NG3L5C)
Old video for AreaShop v1.0: [Tutorial by VariationVault](https://www.youtube.com/watch?v=k2HMCxCCOYo)
@@ -0,0 +1,22 @@
plugins.apply("io.papermc.paperweight.userdev")
dependencies {
paperDevBundle("1.17.1-R0.1-SNAPSHOT")
compileOnly(projects.areashopInterface)
compileOnly(projects.areashopNms)
}
description = "AreaShop NMS Helper 1-17"
tasks {
assemble {
dependsOn("reobfJar")
}
named("reobfJar", io.papermc.paperweight.tasks.RemapJar::class) {
outputJar.set(file("build/libs/${project.name}-${project.version}.jar"))
}
}
@@ -1,12 +1,11 @@
package me.wiefferink.areashop.nms.v1_17_R1;
package me.wiefferink.areashop.adapters.platform.legacy;
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
import net.minecraft.core.BlockPosition;
import net.minecraft.world.level.World;
import net.minecraft.world.level.block.state.IBlockData;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock;
@@ -20,28 +19,28 @@ public class BlockBehaviourImpl implements BlockBehaviourHelper {
@Override
public boolean canPlace(Location location, BlockData blockData) {
Objects.requireNonNull(location.getWorld(), "Null World!");
final BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
final BlockPos blockPos = new BlockPos(location.getX(), location.getY(), location.getZ());
final CraftWorld craftWorld = (CraftWorld) location.getWorld();
final World world = craftWorld.getHandle();
final ServerLevel world = craftWorld.getHandle();
final CraftBlockData craftBlockData = (CraftBlockData) blockData;
final IBlockData ibd = craftBlockData.getState();
return ibd.canPlace(world, blockPosition);
final BlockState ibd = craftBlockData.getState();
return ibd.canSurvive(world, blockPos);
}
@Override
public boolean isBlockValid(Block block) {
final CraftBlock craftBlock = (CraftBlock) block;
final CraftWorld craftWorld = (CraftWorld) craftBlock.getWorld();
final World world = craftWorld.getHandle();
final IBlockData ibd = craftBlock.getNMS();
return ibd.canPlace(world, craftBlock.getPosition());
final ServerLevel world = craftWorld.getHandle();
final BlockState ibd = craftBlock.getNMS();
return ibd.canSurvive(world, craftBlock.getPosition());
}
@Override
public boolean isBlockStateValid(BlockState blockState) {
public boolean isBlockStateValid(org.bukkit.block.BlockState blockState) {
final CraftBlockState craftBlockState = (CraftBlockState) blockState;
final IBlockData ibd = craftBlockState.getHandle();
return ibd.canPlace(craftBlockState.getBlock().getCraftWorld().getHandle(), craftBlockState.getPosition());
final BlockState ibd = craftBlockState.getHandle();
return ibd.canSurvive(craftBlockState.getBlock().getCraftWorld().getHandle(), craftBlockState.getPosition());
}
}
@@ -0,0 +1,15 @@
package me.wiefferink.areashop.adapters.platform.legacy;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
public class LegacyPlatformAdapter implements PlatformAdapter {
private final BlockBehaviourImpl blockBehaviourHelper = new BlockBehaviourImpl();
@Override
public BlockBehaviourHelper blockBehaviourHelper() {
return this.blockBehaviourHelper;
}
}
@@ -0,0 +1,11 @@
dependencies {
compileOnly("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
compileOnly(projects.areashopInterface)
compileOnly(projects.areashopNms)
}
description = "AreaShop NMS Helper 1-18"
tasks {
}
@@ -0,0 +1,28 @@
package me.wiefferink.areashop.adapters.platform.modern;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import java.util.Objects;
public class BlockBehaviourImpl implements BlockBehaviourHelper {
@Override
public boolean canPlace(Location location, BlockData blockData) {
Objects.requireNonNull(location.getWorld(), "Null World!");
return location.getBlock().canPlace(blockData);
}
@Override
public boolean isBlockValid(Block block) {
return block.canPlace(block.getBlockData());
}
@Override
public boolean isBlockStateValid(BlockState blockState) {
return blockState.getBlock().canPlace(blockState.getBlockData());
}
}
@@ -0,0 +1,15 @@
package me.wiefferink.areashop.adapters.platform.modern;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
public class ModernPlatformAdapter implements PlatformAdapter {
private final BlockBehaviourImpl blockBehaviourHelper = new BlockBehaviourImpl();
@Override
public BlockBehaviourHelper blockBehaviourHelper() {
return this.blockBehaviourHelper;
}
}
+6
View File
@@ -0,0 +1,6 @@
description = "AreaShop Paper Helper"
dependencies {
compileOnlyApi(libs.paper)
compileOnlyApi(projects.adapters.platform.platformInterface)
}
@@ -0,0 +1,44 @@
package me.wiefferink.areashop.adapters.platform.paper;
import com.destroystokyo.paper.profile.PlayerProfile;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class PaperOfflinePlayerHelper implements OfflinePlayerHelper {
private final Plugin plugin;
private final Server server;
public PaperOfflinePlayerHelper(Plugin plugin) {
this.plugin = plugin;
this.server = plugin.getServer();
}
@Override
public CompletableFuture<Optional<UUID>> lookupUuidAsync(String username) {
final PlayerProfile profile = this.server.createProfile(username);
final CompletableFuture<Optional<UUID>> future = new CompletableFuture<>();
this.server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
profile.complete(false);
future.complete(Optional.ofNullable(profile.getId()));
});
return future;
}
@Override
public CompletableFuture<OfflinePlayer> lookupOfflinePlayerAsync(String username) {
final CompletableFuture<OfflinePlayer> future = new CompletableFuture<>();
this.server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = plugin.getServer().getOfflinePlayer(username);
future.complete(offlinePlayer);
});
return future;
}
}
@@ -0,0 +1,20 @@
package me.wiefferink.areashop.adapters.platform.paper;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public class PaperPlatform implements MinecraftPlatform {
private final OfflinePlayerHelper offlinePlayerHelper;
public PaperPlatform(@NotNull Plugin plugin) {
this.offlinePlayerHelper = new PaperOfflinePlayerHelper(plugin);
}
@Override
public OfflinePlayerHelper offlinePlayerHelper() {
return this.offlinePlayerHelper;
}
}
@@ -0,0 +1,5 @@
description = "AreaShop Platform Interface"
dependencies {
compileOnlyApi(libs.spigot)
}
@@ -0,0 +1,7 @@
package me.wiefferink.areashop.adapters.platform;
public interface MinecraftPlatform {
OfflinePlayerHelper offlinePlayerHelper();
}
@@ -0,0 +1,15 @@
package me.wiefferink.areashop.adapters.platform;
import org.bukkit.OfflinePlayer;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public interface OfflinePlayerHelper {
CompletableFuture<Optional<UUID>> lookupUuidAsync(String username);
CompletableFuture<OfflinePlayer> lookupOfflinePlayerAsync(String username);
}
@@ -0,0 +1,14 @@
dependencies {
compileOnly(libs.spigot)
compileOnly(projects.areashopInterface)
compileOnly(libs.fastasyncworldeditCore) {
exclude("net.kyori", "adventure-text-minimessage")
}
compileOnly(libs.fastasyncworldeditBukkit) {
exclude("net.kyori", "adventure-text-minimessage")
}
compileOnly(libs.worldguardCore)
compileOnly(libs.worldguardBukkit)
}
description = "AreaShop FastAsyncWorldEdit"
@@ -0,0 +1,336 @@
package me.wiefferink.areashop.adapters.plugins;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.CompletableFuture;
public class FastAsyncWorldEditHandler extends WorldEditInterface {
public FastAsyncWorldEditHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public boolean supportsAsyncOperations() {
return true;
}
@Override
public CompletableFuture<Boolean> restoreRegionBlocksAsync(File rawFile, GeneralRegionInterface regionInterface) {
File targetFile = null;
for (ClipboardFormat formatOption : ClipboardFormats.getAll()) {
for (String extension : formatOption.getFileExtensions()) {
File fileOption = new File(rawFile.getAbsolutePath() + "." + extension);
if (fileOption.exists()) {
targetFile = fileOption;
break;
}
}
}
if (targetFile == null || !targetFile.exists() || !targetFile.isFile()) {
pluginInterface.getLogger().info(() -> "Not restoring region. Schematic not found: " + rawFile);
return CompletableFuture.completedFuture(false);
}
File finalFile = targetFile;
ClipboardFormat format = ClipboardFormats.findByFile(targetFile);
if (format == null) {
pluginInterface.getLogger().warning(() -> "Could not find a clipboard format for file: " + finalFile.getAbsolutePath());
return CompletableFuture.completedFuture(false);
}
BlockVector3 min = regionInterface.getRegion().getMinimumPoint();
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning(() -> "Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return CompletableFuture.completedFuture(false);
}
ProtectedRegion wgRegion = regionInterface.getRegion();
long volume = wgRegion.volume();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return CompletableFuture.completedFuture(false);
}
pluginInterface.debugI(() -> String.format("Attempting to restore using format: %s", format.getName()));
// Bug in which schematic pasting doesn't clear tile entities properly
// We manually remove tile entities in the destination before we paste the schematic
pluginInterface.debugI(() -> "Clearing entities for region: " + regionInterface.getName());
if (pluginInterface.getConfig().getBoolean("forceClearEntities", false) && failedClearEntities(world, region, regionInterface)) {
pluginInterface.getLogger().warning(() -> "Failed to clear tile entities for region: " + regionInterface.getName() + ". Will attempt to past anyway");
}
BlockVector3 dimensions = regionInterface.computeDimensions();
CompletableFuture<Boolean> future = new CompletableFuture<>();
Bukkit.getScheduler().runTaskAsynchronously(pluginInterface.pluginInstance(), () -> {
Clipboard clipboard;
try (InputStream is = new FileInputStream(finalFile);
ClipboardReader reader = format.getReader(is)) {
clipboard = reader.read();
if (!clipboard.getDimensions().equals(dimensions)) {
pluginInterface.getLogger().warning(() -> "Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI(() -> "schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
future.complete(false);
return;
}
} catch (IOException ex) {
pluginInterface.getLogger().warning("An error occurred while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
future.complete(false);
return;
} catch (Exception ex) {
pluginInterface.getLogger().warning(() -> "crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
future.complete(false);
return;
}
final EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().newEditSessionBuilder()
.world(world)
.build();
final Operation operation = new ClipboardHolder(clipboard).createPaste(editSession)
.to(min)
.copyEntities(false) // Don't copy entities as FAWE has bug which doesn't synchronize entity access
.build();
future.complete(true);
try (editSession; clipboard) {
Operations.complete(operation);
future.complete(true);
} catch (WorldEditException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
future.complete(false);
}
});
return future;
}
@Override
public CompletableFuture<Boolean> saveRegionBlocksAsync(File file, GeneralRegionInterface regionInterface) {
final ClipboardFormat format = BuiltInClipboardFormat.FAST;
final File targetFile = new File(file.getAbsolutePath() + "." + format.getPrimaryFileExtension());
ProtectedRegion wgRegion = regionInterface.getRegion();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning(() -> "Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return CompletableFuture.completedFuture(false);
}
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
long volume = region.getVolume();
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return CompletableFuture.completedFuture(false);
}
pluginInterface.debugI(() -> String.format("Trying to save region %s to file %s with format %s", regionInterface.getName(), file.getName(), format.getName()));
CompletableFuture<Boolean> future = new CompletableFuture<>();
Bukkit.getScheduler().runTaskAsynchronously(pluginInterface.pluginInstance(), () -> {
try (OutputStream os = new FileOutputStream(targetFile);
ClipboardWriter writer = format.getWriter(os);
Clipboard clipboard = new BlockArrayClipboard(region)) {
try (EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().newEditSessionBuilder()
.world(world)
.build()) {
final ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
// Don't copy entities as FAWE has bug which doesn't synchronize entity access
copy.setCopyingEntities(false);
Operations.complete(copy);
}
writer.write(clipboard);
future.complete(true);
return;
} catch (IOException | WorldEditException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
} catch (Exception ex) {
pluginInterface.getLogger().warning(() -> "crashed during save of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
future.complete(false);
});
return future;
}
@Override
public boolean restoreRegionBlocks(File rawFile, GeneralRegionInterface regionInterface) {
File targetFile = null;
for (ClipboardFormat formatOption : ClipboardFormats.getAll()) {
for (String extension : formatOption.getFileExtensions()) {
File fileOption = new File(rawFile.getAbsolutePath() + "." + extension);
if (fileOption.exists()) {
targetFile = fileOption;
break;
}
}
}
if (targetFile == null || !targetFile.exists() || !targetFile.isFile()) {
pluginInterface.getLogger().info(() -> "Not restoring region. Schematic not found: " + rawFile);
return false;
}
File finalFile = targetFile;
ClipboardFormat format = ClipboardFormats.findByFile(targetFile);
if (format == null) {
pluginInterface.getLogger().warning(() -> "Could not find a clipboard format for file: " + finalFile.getAbsolutePath());
return false;
}
BlockVector3 min = regionInterface.getRegion().getMinimumPoint();
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning(() -> "Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
long volume = regionInterface.getRegion().volume();
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return false;
}
pluginInterface.debugI(String.format("Attempting to restore using format: %s", format.getName()));
// Bug in which schematic pasting doesn't clear tile entities properly
// We manually remove tile entities in the destination before we paste the schematic
pluginInterface.debugI(() -> "Clearing entities for region: " + regionInterface.getName());
ProtectedRegion wgRegion = regionInterface.getRegion();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
if (pluginInterface.getConfig().getBoolean("forceClearEntities", false) && failedClearEntities(world, region, regionInterface)) {
pluginInterface.getLogger().warning(() -> "Failed to clear tile entities for region: " + regionInterface.getName() + ". Will attempt to past anyway");
}
BlockVector3 dimensions = regionInterface.computeDimensions();
try (InputStream is = new FileInputStream(finalFile);
ClipboardReader reader = format.getReader(is)) {
Clipboard clipboard = reader.read();
if (!clipboard.getDimensions().equals(dimensions)) {
pluginInterface.getLogger().warning(() -> "Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI(() -> "schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
return false;
}
final Operation operation = new ClipboardHolder(clipboard).createPaste(world)
.to(min)
.copyEntities(false)
.build();
Operations.complete(operation);
return true;
} catch (IOException | WorldEditException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
} catch (Exception ex) {
pluginInterface.getLogger().warning(() -> "crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
return false;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
final ClipboardFormat format = BuiltInClipboardFormat.FAST;
final File targetFile = new File(file.getAbsolutePath() + "." + format.getPrimaryFileExtension());
ProtectedRegion wgRegion = regionInterface.getRegion();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
long volume = region.getVolume();
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return false;
}
pluginInterface.debugI(() -> String.format("Trying to save region %s to file %s with format %s", regionInterface.getName(), file.getName(), format.getName()));
try (OutputStream os = new FileOutputStream(targetFile);
ClipboardWriter writer = format.getWriter(os);
Clipboard clipboard = new BlockArrayClipboard(region)) {
try (EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().newEditSessionBuilder()
.world(world)
.build()) {
final ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setCopyingEntities(true);
Operations.complete(copy);
}
writer.write(clipboard);
return true;
} catch (IOException | WorldEditException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
} catch (Exception ex) {
pluginInterface.getLogger().warning("crashed during save of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
return false;
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
try {
Region region = pluginInterface.getWorldEdit().getSession(player)
.getSelection(BukkitAdapter.adapt(player.getWorld()));
return new WorldEditSelection(player.getWorld(),
BukkitAdapter.adapt(player.getWorld(), region.getMinimumPoint()),
BukkitAdapter.adapt(player.getWorld(), region.getMaximumPoint()));
} catch (IncompleteRegionException e) {
return null;
}
}
private boolean failedClearEntities(World world, Region region, GeneralRegionInterface regionInterface) {
try (EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().newEditSessionBuilder()
.world(world)
.build()) {
EntityFunction function = entity -> {
EntityType entityType = entity.getType();
if (entityType != null && (entityType.equals(EntityTypes.ITEM_FRAME)
|| entityType.equals(EntityTypes.PAINTING)
|| entityType.equals(EntityTypes.LEASH_KNOT)) && !entity.remove()) {
pluginInterface.debugI("Could not remove entity: " + entityType.getName());
}
return false;
};
EntityVisitor visitor = new EntityVisitor(editSession.getEntities(region).iterator(), function);
Operations.complete(visitor);
return false;
} catch (WorldEditException ex) {
pluginInterface.getLogger().warning("crashed during save of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(ex));
return true;
}
}
}
@@ -0,0 +1,9 @@
dependencies {
compileOnly(libs.spigot)
compileOnly(projects.areashopInterface)
compileOnly(libs.worldeditCore)
compileOnly(libs.worldeditBukkit)
compileOnly(libs.worldguardCore)
}
description = "AreaShop WorldEdit 7"
@@ -0,0 +1,221 @@
package me.wiefferink.areashop.adapters.plugins;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;
public class WorldEditHandler extends WorldEditInterface {
public WorldEditHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
try {
Region region = pluginInterface.getWorldEdit().getSession(player).getSelection(BukkitAdapter.adapt(player.getWorld()));
return new WorldEditSelection(
player.getWorld(),
BukkitAdapter.adapt(player.getWorld(), region.getMinimumPoint()),
BukkitAdapter.adapt(player.getWorld(), region.getMaximumPoint())
);
} catch (IncompleteRegionException e) {
return null;
}
}
@Override
public boolean restoreRegionBlocks(File rawFile, GeneralRegionInterface regionInterface) {
File targetFile = null;
for (ClipboardFormat formatOption : ClipboardFormats.getAll()) {
for (String extension : formatOption.getFileExtensions()) {
File fileOption = new File(rawFile.getAbsolutePath() + "." + extension);
if (fileOption.exists()) {
targetFile = fileOption;
break;
}
}
}
if (targetFile == null || !targetFile.exists() || !targetFile.isFile()) {
pluginInterface.getLogger().info(() -> "Not restoring region. Schematic not found: " + rawFile);
return false;
}
File finalFile = targetFile;
ClipboardFormat format = ClipboardFormats.findByFile(targetFile);
if (format == null) {
pluginInterface.getLogger().warning(() -> "Could not find a clipboard format for file: " + finalFile.getAbsolutePath());
return false;
}
BlockVector3 min = regionInterface.getRegion().getMinimumPoint();
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning(() -> "Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
long volume = regionInterface.getRegion().volume();
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return false;
}
pluginInterface.debugI(() -> String.format("Attempting to restore using format: %s", format.getName()));
// Bug in which schematic pasting doesn't clear tile entities properly
// We manually remove tile entities in the destination before we paste the schematic
pluginInterface.debugI(() -> "Clearing entities for region: " + regionInterface.getName());
ProtectedRegion wgRegion = regionInterface.getRegion();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
if (pluginInterface.getConfig().getBoolean("forceClearEntities", false) && failedClearEntities(world, region, regionInterface)) {
pluginInterface.getLogger().warning(() -> "Failed to clear tile entities for region: " + regionInterface.getName() + ". Will attempt to past anyway");
}
BlockVector3 dimensions = regionInterface.computeDimensions();
try (InputStream is = new FileInputStream(finalFile);
ClipboardReader reader = format.getReader(is)) {
Clipboard clipboard = reader.read();
if (!clipboard.getDimensions().equals(dimensions)) {
pluginInterface.getLogger().warning(() -> "Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI("schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
return false;
}
final Operation operation = new ClipboardHolder(clipboard).createPaste(world)
.to(min)
.copyEntities(true)
.build();
Operations.complete(operation);
return true;
} catch (IOException | WorldEditException ex) {
pluginInterface.getLogger().warning(() ->"An error occurred while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
} catch (Exception ex) {
pluginInterface.getLogger().warning(() -> "crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
return false;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
final ClipboardFormat format = BuiltInClipboardFormat.SPONGE_SCHEMATIC;
final File targetFile = new File(file.getAbsolutePath() + "." + format.getPrimaryFileExtension());
ProtectedRegion wgRegion = regionInterface.getRegion();
Region region = new CuboidRegion(wgRegion.getMinimumPoint(), wgRegion.getMaximumPoint());
final World world = BukkitAdapter.adapt(regionInterface.getWorld());
if (world == null) {
pluginInterface.getLogger().warning(() -> "Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
int maxBlocks = pluginInterface.getConfig().getInt("maximumBlocks", Integer.MAX_VALUE);
long volume = region.getVolume();
if (volume > maxBlocks) {
pluginInterface.getLogger().warning((() -> "Region is bigger than the max allowed block change size! Volume: " + volume + " Limit: " + maxBlocks));
return false;
}
pluginInterface.debugI(() -> String.format("Trying to save region %s to file %s with format %s", regionInterface.getName(), file.getName(), format.getName()));
Clipboard clipboard = new BlockArrayClipboard(region);
final ForwardExtentCopy copy = new ForwardExtentCopy(world, region, clipboard, region.getMinimumPoint());
copy.setCopyingEntities(true);
try {
Operations.complete(copy);
} catch (WorldEditException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
try (OutputStream os = new FileOutputStream(targetFile);
ClipboardWriter writer = format.getWriter(os)) {
writer.write(clipboard);
return true;
} catch (IOException ex) {
pluginInterface.getLogger().warning(() -> "An error occurred while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
} catch (Exception ex) {
pluginInterface.getLogger().warning(() -> "crashed during save of " + regionInterface.getName());
pluginInterface.debugI(() -> ExceptionUtils.getStackTrace(ex));
}
return false;
}
private boolean failedClearEntities(World world, Region region, GeneralRegionInterface regionInterface) {
try (EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().newEditSessionBuilder()
.world(world)
.build()) {
EntityFunction function = entity -> {
BaseEntity state = entity.getState();
if (state == null) {
return false;
}
EntityType entityType = state.getType();
if ((entityType.equals(EntityTypes.ITEM_FRAME)
|| entityType.equals(EntityTypes.PAINTING)
|| entityType.equals(EntityTypes.LEASH_KNOT))
&& !entity.remove()) {
pluginInterface.debugI("Could not remove entity: " + entityType.getName());
}
return false;
};
EntityVisitor visitor = new EntityVisitor(editSession.getEntities(region).iterator(), function);
Operations.complete(visitor);
return false;
} catch (WorldEditException ex) {
pluginInterface.getLogger().warning("crashed during save of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(ex));
return true;
}
}
}
@@ -0,0 +1,9 @@
dependencies {
compileOnly(libs.spigot)
compileOnly(projects.areashopInterface)
compileOnly(libs.worldeditCore)
compileOnly(libs.worldeditBukkit)
compileOnly(libs.worldguardCore)
}
description = "AreaShop WorldGuard 7"
@@ -1,4 +1,4 @@
package me.wiefferink.areashop.handlers;
package me.wiefferink.areashop.adapters.plugins;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector2;
@@ -27,9 +27,9 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
public class WorldGuardHandler7 extends WorldGuardInterface {
public class WorldGuardHandler extends WorldGuardInterface {
public WorldGuardHandler7(AreaShopInterface pluginInterface) {
public WorldGuardHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>
-6
View File
@@ -1,6 +0,0 @@
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly project(':areashop-interface')
}
description = 'AreaShop Bukkit 1.13 and higher'
@@ -1,77 +0,0 @@
package me.wiefferink.areashop.handlers;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
public class BukkitHandler1_13 extends BukkitInterface {
public BukkitHandler1_13(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
// Uses BlockData, which does not yet exist in 1.12-
@Override
public BlockFace getSignFacing(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if(blockData instanceof WallSign) {
return ((WallSign) blockData).getFacing();
} else if(blockData instanceof Sign) {
return ((Sign) blockData).getRotation();
}
return null;
}
// Uses BlockData, WallSign and Sign which don't exist in 1.12-
@Override
public boolean setSignFacing(Block block, BlockFace facing) {
if (block == null || facing == null) {
return false;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if(blockData instanceof WallSign) {
((WallSign) blockData).setFacing(facing);
} else if(blockData instanceof Sign) {
((Sign) blockData).setRotation(facing);
} else {
return false;
}
block.setBlockData(blockData);
return true;
}
@Override
public Block getSignAttachedTo(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
BlockData blockData = blockState.getBlockData();
if(blockData instanceof WallSign) {
return block.getRelative(((WallSign) blockData).getFacing().getOppositeFace());
} else if(blockData instanceof Sign) {
return block.getRelative(BlockFace.DOWN);
}
return null;
}
}
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>
-7
View File
@@ -1,7 +0,0 @@
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.5'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
}
description = 'AreaShop Interface'
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff. Show more