Compare commits

...
561 Commits
Author SHA1 Message Date
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
md5sha256 363b416c59 Retain compat for FileManager 2021-10-10 03:48:12 +08:00
md5sha256 7bf516108b Rename AreaShop again and fix teleport feature 2021-10-09 22:22:53 +08:00
md5sha256 7567cb5fe4 Cleanup global features 2021-10-09 21:33:19 +08:00
md5sha256 d2ca54e8ea Fix signs not updating 2021-10-09 21:03:25 +08:00
md5sha256 e47cda4254 Fix plugin.yml 2021-10-09 17:44:01 +08:00
md5sha256 98d4c6a778 Fix relocations and cleanup DI for Economy and Permission 2021-10-09 17:40:10 +08:00
md5sha256 2a44dd29cc Fix relocations 2021-10-09 17:29:36 +08:00
md5sha256 c1665c33ff Finish cleaning up DI 2021-10-09 17:24:28 +08:00
md5sha256 2cdab9b6db Initial work on guice 2021-10-09 13:27:46 +08:00
md5sha256 72faf76619 Fix ClassCastException in RegionSign 2021-10-09 13:27:28 +08:00
md5sha256 ad66ce00b1 Actually register the sign listener 2021-10-09 02:00:38 +08:00
md5sha256 edc7126b87 Performance improvements to FileManager and various commands 2021-10-09 01:02:00 +08:00
md5sha256 a7f0ac248c Initial work on sign refactoring 2021-10-08 17:44:43 +08:00
md5sha256 675dee2cd3 Add sign error logger 2021-10-07 03:12:45 +08:00
md5sha256 c7226750ab Don't check for WG v5 2021-10-07 01:36:36 +08:00
md5sha256 2ecbb61053 Performance improvements for the teleport feature 2021-10-07 01:34:18 +08:00
md5sha256 fc132558a3 Add a BlockBehaviourHelper 2021-10-07 01:24:20 +08:00
md5sha256 b172413b62 Minor performance improvements 2021-10-07 00:11:09 +08:00
md5sha256 dcbb1f5896 Fix buildscripts and Java 16 support 2021-10-06 23:59:23 +08:00
md5sha256 6e3855c0c3 Remove legacy modules, remove use of ScriptEngine 2021-10-06 23:46:58 +08:00
md5sha256 27991d17a2 Gradle 2021-10-06 23:39:57 +08:00
md5sha256 159221d53d Initial work on updating to 1.17 2021-10-05 23:45:25 +08:00
dependabot[bot] 557d11dfb4 Bump checkstyle from 8.21 to 8.29
Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.21 to 8.29.
- [Release notes](https://github.com/checkstyle/checkstyle/releases)
- [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.21...checkstyle-8.29)

Signed-off-by: dependabot[bot] <support@github.com>
2020-02-26 11:02:43 +01:00
Thijs Wiefferink b9547e2c67 Remove github action experiment 2019-08-16 18:22:19 +02:00
Thijs Wiefferink 221785ae55 Add test workflow maven build 2019-08-16 17:42:22 +02:00
Thijs Wiefferink 0d04676bce Fix including bukkit into the AreaShop jar 2019-06-23 22:27:35 +02:00
Thijs Wiefferink c8cd68c17b Fixup javadoc build 2019-06-23 22:07:34 +02:00
Thijs Wiefferink 539887449c pom.xml: build with craftbukkit 1.13 2019-06-23 21:59:04 +02:00
Thijs Wiefferink 4cda8a9292 Fix sign handling for 1.14
- Setup modules to load different classes for different Bukkit/Spigot versions
- Create BukkitHandler to get/set the sign facing and get the block it is attached to
- Fix `/as addsign` to use new sign methods
- Fix sign updates to use new sign methods
- Implement full forwards and backwards compatibility of the saved sign material type
    - On Bukkit 1.12 and lower all special wood types are translated to the standard sign
    - On Bukkit 1.13 the internal sign name is translated (and special wood types to the standard one)
    - On Bukkit 1.14 the signs of 1.13- are translated to the OAK variants
- Cleanup the .gitignore files inside of the module folders
2019-06-23 21:53:48 +02:00
Thijs Wiefferink fe131dc157 BuyRegion/RentRegion: fix %player% placeholders for selling/unrenting confirmation messages 2019-06-16 21:40:58 +02:00
Thijs Wiefferink 41ced9ee6c Update checkstyle from 7.6 to 8.21 2019-06-01 17:08:30 +02:00
Thijs Wiefferink 03de0ff252 default.yml: fix spelling mistake 2019-06-01 16:24:15 +02:00
Thijs Wiefferink b057271394 Fix permission check of /as rent, fix 'already bought' check of /as buy 2019-02-20 19:33:37 +01:00
Thijs Wiefferink d7cdff0b22 /as setteleport: fix check that hides it from /as help 2019-02-08 22:29:57 +01:00
Thijs Wiefferink 1035b6b41b Move event commands to a feature class, add two events
- Move eventCommandProfile code to a separate class
- Add AddingRegionEvent
- Add DeletingRegionEvent
- Cleanup a couple of duplicate code paths (merge RentRegion/BuyRegion branches)
2019-01-28 23:37:43 +01:00
Thijs Wiefferink e0bad7397c Refactoring based on SonarLint and Intellij IDEA inspections 2019-01-26 21:23:49 +01:00
Thijs Wiefferink b7124e8cdd Remove mcstats.org metrics class, I don't believe they will be online again 2019-01-26 20:11:26 +01:00
Thijs Wiefferink f0952c32c9 Update issue templates
Add 'NEW' label to issues created using the template
2019-01-13 22:26:54 +01:00
Thijs Wiefferink d3dfa86a65 Set version to 2.6.0 2019-01-13 17:34:50 +01:00
Thijs Wiefferink 8f73b8af3c documentation/release.md: add instructions for releasing a new version 2019-01-13 17:34:37 +01:00
Thijs Wiefferink 51b24c74b4 langHeader.yml: add the template used to generate the language file headers to the repository 2019-01-13 17:33:54 +01:00
Thijs Wiefferink 9beb1eb61b Move the changelog from the wiki to the repository 2019-01-13 17:33:09 +01:00
Thijs Wiefferink de5fdafca0 Pull translations from Transifex 2019-01-08 21:18:19 +01:00
Thijs Wiefferink 0aea914d20 Add FastAsyncWorldEdit support on Spigot 1.13
- FastAsyncWorldEdit now supported on Spigot 1.13
- Improved support for the beta-01 versions of WorldGuard and WorldEdit
- Resolves #436
2019-01-08 00:19:48 +01:00
Thijs Wiefferink b4efe7d5bf Add default labels to issue templates 2019-01-05 16:27:05 +01:00
Thijs Wiefferink ec7983e126 Fix handling of sign updates at places where they will pop off immediately
1. When placing back a missing sign it could be placed in the middle of the air
2. BlockPhysicsEvent would fire immediately (synchronously) breaking the sign
3. Sign update would break because the sign has not actually been placed
2019-01-01 19:32:34 +01:00
Thijs Wiefferink e45c353030 Fix detecting region by location when using WorldEdit 7 beta-2 or later
- The WorldEdit 7 beta-2 handler was inheriting a function from the handler of older version that uses the old Vector class
- Fixes #466
- Fixes #467
2019-01-01 19:30:16 +01:00
Thijs Wiefferink 44b1cb0fc8 /as add: fix setting player as landlord when he is an owner of the region
- Fixes #427
- Adds a debug message to check the behavior easily in the future
2018-12-28 17:11:48 +01:00
Thijs Wiefferink c7299fa56c Update Discord image to a widget image 2018-12-27 23:14:56 +01:00
pmme 12bf467714 Simplify WorldEdit 7 flushQueue vs. flushSession 2018-12-27 22:47:14 +01:00
Thijs Wiefferink 5b327db316 signs: instead of cancelling indirect break, remove the sign to prevent lagg 2018-12-27 19:44:30 +01:00
Thijs Wiefferink b4f33589a1 Cleanup old directory 2018-12-27 17:45:19 +01:00
Thijs Wiefferink 530c74ccd2 Add support for the WorldEdit vector refactor update
- Add WorldEdit and WorldGuard module that supports the new vector system
- WorldGuard/WordEdit dependencies are in the repository itself to make builds more reliable
- Change code that uses WorldEdit vectors to use Spigot vectors
- Rename all modules to areashop-[worldguard|worldedit]-<version>
- Change maven versions of internal modules to 'latest' to be less confusing
2018-12-27 17:42:24 +01:00
Thijs Wiefferink fa4857cbce Simplify code in the handler for WorldEdit 7 2018-12-27 15:00:53 +01:00
Thijs Wiefferink 93fd4e96cb Fix restoring schematics for the latest WorldEdit dev builds
- Fixes #447
- Thanks pmme and x1p for reporting the issue!
2018-10-28 17:58:09 +01:00
Thijs Wiefferink a6863ae782 Also put the Vault dependency into /dependencies
- Now it should be easy again to built AreaShop yourself, only need to run BuildTools for 1.13.0 and it should work
2018-10-28 01:15:12 +02:00
Thijs Wiefferink e5e2c4ca08 Fixup dependencies, use Bukkit/CraftBukkit 1.7.9 instead of 1.8
- 1.7.9 is the lowest supported version, so it is good to use that as base
2018-10-28 00:53:30 +02:00
Thijs Wiefferink b0341e2a3e Fix compatibility with 1.13 Material class
- Fixes sign handling to properly detect and store signs, fixes #440
- Fixes safe teleporting (also improves block detection, making it even safer)
2018-10-28 00:12:24 +02:00
Thijs Wiefferink c8e1ebb068 Change WorldGuard/WorldEdit/Bukkit dependencies to file links
- Fixes the issue that olders WorldEdit and Bukkit versions are not available on Maven anymore
- This speeds up the build a lot
2018-10-28 00:00:41 +02:00
Thijs Wiefferink 39c8eb5f73 Fix tab complete types for /as setduration 2018-10-22 23:44:31 +02:00
Thijs Wiefferink 2483cf1614 Try to add compatibility with the FAWE schematic format 2018-10-21 21:59:45 +02:00
Thijs Wiefferink 769f8ee4ca Set version to 2.5.0, ready for release! 2018-10-20 21:58:14 +02:00
Thijs Wiefferink 2c04b87a9f Add the latest Transifex translations for DE, ES and FR 2018-10-20 21:57:05 +02:00
Thijs Wiefferink 8ce1ed0264 Fix showing /as del and /as add in /help for landlords 2018-10-20 18:36:51 +02:00
Thijs Wiefferink 035f8e1932 Possibly fix default value for areashop.limits.default (documentation is inconsistent for not op) 2018-10-20 18:36:51 +02:00
Thijs Wiefferink 4d3482994f Smaller discord image 2018-10-20 15:53:14 +02:00
Thijs Wiefferink 45f1c510e5 Add link to the AreaShop Discord 2018-10-20 15:49:36 +02:00
Thijs Wiefferink 5c13223b9e Fix for 1.13.1, depend on WorldGuard and WorldEdit 7 beta-01 2018-10-20 14:54:52 +02:00
Thijs Wiefferink 8c47ae9b3c Add README.md files in a couple of packages, closes #128 2018-08-12 16:41:03 +02:00
Thijs Wiefferink 28d03a6a3a Small fixes suggested by Intellij IDEA 2018-08-12 16:23:43 +02:00
Thijs Wiefferink aa585e9b11 Deal with empty date/time settings (handle as 'unlimited'/'disabled')
- Fixes #412
2018-08-12 16:17:02 +02:00
Thijs Wiefferink 36d2ce60b9 Disable copying entities (WorldEdit 7), and enable removing entities (WorldEdit 6)
- Fixes security problem of #273:
    - Throw item into a region
    - Rent/buy the region -> it gets saved as schematic
    - Pick up items
    - Unrent/sell the region -> items appear again
    - Pick up second set of items, they got duplicated
2018-08-11 22:31:15 +02:00
Thijs Wiefferink bdea9448a4 Update WorldEdit 7 to build 3817, update WorldGuard 7 to build 1735 2018-08-11 22:19:25 +02:00
Thijs Wiefferink bd2f40f5c8 Use new schematic format when using WorldEdit 7 2018-08-11 22:18:48 +02:00
Thijs Wiefferink 9e908cee73 Fix getting region by location for WorldGuard 7 2018-08-11 22:17:13 +02:00
Thijs Wiefferink 0d326d973d Fix saving/restoring schematics with WorldEdit 7 2018-08-05 12:23:32 +02:00
Thijs Wiefferink 27eaa27765 Add WorldGuard 7 and WorldEdit 7 support, now 1.13 works
- Closes #411
2018-08-05 00:34:50 +02:00
Thijs Wiefferink fb35153eb2 Pull translations from Transifex 2018-07-22 17:52:25 +02:00
Thijs Wiefferink aec6295516 Remove dependency on javafx 2018-06-17 17:14:23 +02:00
Thijs Wiefferink 38cd77e487 Fix compilation error in the import command 2018-06-01 19:54:02 +02:00
Thijs Wiefferink 6b9866a4c4 Ignore hidden files in the /regions directory (like .DS_Store) 2018-05-29 22:58:15 +02:00
Thijs Wiefferink 5aceb81cfd Import: setup permanent region settings when not rentable and buyable 2018-05-29 22:21:43 +02:00
Thijs Wiefferink 50f6bce64e Fix region limits, thanks @ZachryWilsn for reporting! 2018-05-29 21:59:55 +02:00
Thijs Wiefferink f713edc5b5 Disable moneyback message in /as info if sellDisabled is true 2018-05-26 01:33:23 +02:00
Thijs Wiefferink 012920a51c Cleanups because of Intellij IDEA inspections 2018-05-23 23:46:57 +02:00
Thijs Wiefferink 6154454f96 Indicate if a region has already been added with another world
- Closes #287
2018-05-23 22:53:07 +02:00
Thijs Wiefferink e34daeb5ff Update readme to use issue template selection link 2018-05-23 22:38:12 +02:00
Thijs Wiefferink 0a2dc22c59 Setup issue templates 2018-05-23 22:29:29 +02:00
Thijs Wiefferink 2482bd88c2 Add option to ignore regions for limit calculation
Set `countForLimit` to `false` in default.yml, a group or the region file to ignore it for limits
2018-05-23 22:13:42 +02:00
Thijs Wiefferink e86281ab28 Safer sign update, don't assume location/world still exists 2018-05-12 14:41:45 +02:00
Thijs Wiefferink 5a9ca74b75 Add option to disable selling and reselling your own regions 2018-05-10 20:07:10 +02:00
Thijs Wiefferink d301be2304 Add licence, issues and CI to the root pom file 2018-04-03 22:44:16 +02:00
Thijs Wiefferink a23c6fa66f Hide progress messages of region update, speed up region updates 2018-04-02 20:05:38 +02:00
Thijs Wiefferink cd63517041 Fix list of region names for error indicating missing worlds 2018-04-02 20:00:22 +02:00
Thijs Wiefferink e3043c476b Fix available languages link 2018-04-02 12:10:34 +02:00
Thijs Wiefferink 3be7573863 Parse currency prefix and suffix with InteractiveMessenger
- Allows proper colors and escaping
2018-03-09 11:50:08 +01:00
Thijs Wiefferink 51161fffee Remove unused chunkunload event 2018-03-09 11:08:15 +01:00
Thijs Wiefferink c82067ad0b Add back Paypal donate button 2018-02-17 19:04:18 +01:00
Thijs Wiefferink 46dbb8d22c More customizable metric suffixes, better currency formatting
- 'metricSymbols' section in 'config.yml' to customize the used suffixes for large numbers
- Remove trailing zeros from numbers with metric suffix
- Properly handle rounding of 1.235 to 1.24 (different double to BigDecimal conversion)
- Closes #373
2018-02-12 14:44:48 +01:00
Thijs Wiefferink cace086466 Add UTF8 awareness flag in plugin.yml
- I think it only does something if you use JavaPlugin#getConfig(), but it does not harm either
2018-02-12 12:49:04 +01:00
Thijs Wiefferink 06a716b1fd Make %uuid% available to schematics when selling a region
- Schematic save/restore would happen after removing the owner, which means %uuid% would be null
- Unrenting already does the save/restore before removing the renter, so now it is more consistent
- Thanks to Behoston on Github for reporting the issue
- Closes #383
2018-02-01 13:59:48 +01:00
Thijs Wiefferink 4530717045 Command confirmation for /as import
- Can also be used for all WordEdit based add/delete actions in the future
2018-01-26 16:16:11 +01:00
Thijs Wiefferink 741bbd879f Fix hashCode() of RegionSign 2018-01-26 14:33:27 +01:00
Thijs Wiefferink 8474edd29d Save region name as given to /as add and /as stack
- Previously the WorldGuard region id was used, converting the name to lowercase
2018-01-26 13:55:41 +01:00
Thijs Wiefferink d4df691166 FIx usage of > in javadocs 2018-01-26 12:15:10 +01:00
Thijs Wiefferink 3e247e6cb1 Move sign listeners into SignsFeature
- Fix removing signs not removing it from the signsByChunk map
2018-01-26 12:08:22 +01:00
Thijs Wiefferink f3527134e8 Prevent chunk loading by sign updates
- When sign needs update, only do it if the chunk is already loaded
- If a chunk gets loaded (by a player or something else), update any signs in that chunk
- Improve some javadocs, let checkstyle require @param, @throws and @returns
2018-01-22 18:12:15 +01:00
Thijs Wiefferink 0e14b121b8 InfoCommand: fix showing list of signs (was only showing the first one) 2018-01-22 18:08:16 +01:00
Thijs Wiefferink 8cc632fc05 Pull latest translations from Transifex (automated script) 2018-01-22 16:31:03 +01:00
Thijs Wiefferink 77c1b3f288 Fix error in help message of the import command 2018-01-22 16:10:02 +01:00
Thijs Wiefferink 21339cbf7c Fix incorrect message reference for /as message 2018-01-22 16:07:52 +01:00
Thijs Wiefferink 0351188671 Update live support link 2018-01-21 22:10:02 +01:00
Thijs Wiefferink 47e1d80821 Add live support chat link to 99messages 2018-01-18 16:16:40 +01:00
Thijs Wiefferink 1d0472b052 Improve feedback when placing [as] sign for region that is not added 2017-12-22 12:25:30 +01:00
Thijs Wiefferink 22dcfc76af Fix confirmation messages of /as del (failed refactor)
Thanks Noudux for reporting it!
2017-12-21 18:09:55 +01:00
Thijs Wiefferink 6b59176048 Fix startup error: call init method of the scheduling library 2017-11-27 10:02:51 +01:00
Thijs Wiefferink 5dc4d11408 Fix missing spaces in /as message messages 2017-11-26 23:49:42 +01:00
Thijs Wiefferink 00bd305381 Use Map#putIfAbsent where applicable 2017-11-26 16:01:05 +01:00
Thijs Wiefferink 9daa50b23b Use BukkitDo scheduling library
- Much cleaner code for scheduling tasks,
- Makes proper use of Java 8 functionality
2017-11-26 15:47:51 +01:00
Thijs Wiefferink 33b73a0369 Remove Paypal donate button 2017-11-25 17:07:54 +01:00
Thijs Wiefferink 591540af30 Partially fix problem with importing regions from RegionForSale
- When checking the type of a region AreaShop would only look at the settings of the region, not the settings of the world, parent regions and config.yml
- Checking parent regions for these settings should still be added (requires bigger changes)
2017-11-23 22:54:55 +01:00
Thijs Wiefferink 4e1e50e993 Fix /as linksigns <profile> for configs without signProfiles
The `signProfiles` section is not in the default config.yml file anymore, so getting that section can return null
2017-11-20 09:19:35 +01:00
Thijs Wiefferink 9a52ca3d9b Add missing @return Javadoc for RegionGroup#getAutoRegions() 2017-11-10 00:04:39 +01:00
Thijs Wiefferink 858b019806 Add option to teleport X blocks away from the sign
- Implements #364
- Option `general.teleportSignDistance` to `default.yml` to set the number of blocks to teleport away from the sign
- Changes the pitch/yaw of the player so that he faces the sign
- Handles wall and floor signs in any direction
- Improve SignsFeature code structure
2017-11-09 23:56:18 +01:00
Thijs Wiefferink b1dfe93088 Add RegionForSale import, rental auto-extend and other things
- `/as import RegionForSale`, as requested in #98:
    - Imports all regions from RegionForSale
    - Converts almost all settings to their AreaShop equivalent
    - Handles parent regions
- Add `rent.autoExtend` for use with rental regions to automatically extend the rent when the time is out, start of #29, still need the command
    - Vault compatible permissions plugin is required to let this work while the player is offline
    - All permissions, limits and the player balance are checked as during a normal rent
- Add option to region groups to automatically add all regions of a certain world
- BREAKING: Region events now use OfflinePlayer instead of Player
- Automatically import existing region owners/members when adding a region to AreaShop

There are still a couple of things missing in the import and it needs to be tested a lot.
2017-10-20 13:41:30 +02:00
Thijs Wiefferink 0bf2314f2a Add licence (as already listed on BukkitDev) 2017-10-16 11:56:04 +02:00
Thijs Wiefferink 33ddb8ae88 Fix %volume% for polygon regions
- WorldGuard does not implement volume() for Polygon regions, always returns 0
- Volume result is cached, calculating it for polygon regions could be slow
2017-10-05 16:53:42 +02:00
Thijs Wiefferink 234e4b6261 Prevent indirectly breaking signs with non-solid blocks
- Fixes #358
2017-10-05 13:43:27 +02:00
Thijs Wiefferink ed2ffaeaa3 Move base command to EN.yml for /as info paging 2017-10-05 13:15:51 +02:00
Thijs Wiefferink e073438862 Add %volume% variable to get the number of blocks in a region
- Works properly for polygon regions
2017-10-05 12:20:03 +02:00
Thijs Wiefferink 07194f07da Add region masking to schematic restore
- When restoring a schematic the paste is masked to the region blocks, so that only blocks that are actually inside the region are pasted (necessary for polygon regions)
- Closes #20
2017-10-01 19:49:05 +02:00
Thijs Wiefferink dfa3e0be66 Checkstyle fix 2017-09-04 17:09:31 +02:00
Thijs Wiefferink 8eef029400 Fix %month% variable using 0-11 instead of 1-12
- Fixes #354, thanks skippyaut
2017-09-04 16:58:39 +02:00
Thijs Wiefferink c8d869ce15 Fix usage of teleport location set by '/as settp'
- It was accidentally trying to get the teleport location from the plugin config file instead of the region config file.
- Also added the possibility to set the teleport location in groups and default.yml
2017-08-05 20:25:06 +02:00
Thijs Wiefferink 053d75181d Update to InteractiveMessenger 1.1-SNAPSHOT
- Ensures AreaShop is rebuild when InteractiveMessenger updates
- Fixes crash bug that was in InteractiveMessenger
- Fixes #334
2017-07-30 17:25:49 +02:00
Thijs Wiefferink f0128c221b Update README.md 2017-06-23 14:59:16 +02:00
Thijs Wiefferink ce6c01c5d0 Add Transifex translation stats image 2017-06-23 14:54:19 +02:00
Thijs Wiefferink b835c4dded Only reset WorldGuard flag/groupFlag if not already empty 2017-06-12 22:05:09 +02:00
Thijs Wiefferink 07e6782714 Fix /as setowner for regions that are not rented yet
Add a rental period to the time when setting owner of a rental region that is not rented yet, otherwise it would get expired immediately
2017-06-12 21:58:42 +02:00
Thijs Wiefferink 4002956aeb Fix javadoc comments 2017-06-12 20:42:36 +02:00
Thijs Wiefferink 0b96b9cb42 Github update checker, Java 8
- Add Github update checker, closes #201, it is implemented to allow reuse by other plugins, it will probably move to a separate repository later
- Switch to Java 8, if people did not update already they probably never will
- Add used Bukkit version as property, use that in all pom files
- Add Task class with methods to easily use BukkitRunnable (not all code is migrated to this pattern yet)
2017-06-12 20:39:28 +02:00
Thijs Wiefferink 0c192c2444 Cleanup setOwners/setMembers, only edit WorldGuard region if different
- Improve code layout for changing owners and members of WorldGuard regions
- Only edit flags and other WorldGuard region settings if they are different than the current option, this prevents useless saves in WorldGuard (which shows a message in console)
2017-06-12 20:39:28 +02:00
Thijs Wiefferink 2381aaeacc Remove link to Shop plugin because it is not fixed yet 2017-04-30 14:15:35 +02:00
Thijs Wiefferink 906b331758 Fix line endings in config.yml 2017-04-20 23:35:49 +02:00
Thijs Wiefferink f0f2e09be0 Always add English time indicators
- Internal timers specified using settings in hiddenConfig.yml use the English words, so if you remove the English words from config.yml timers do not run (regions not expiring, no notifications, no file saving)
- Warn in console when an unknown time specifier is found, might get spammy but at least gets the point across
2017-04-20 23:23:57 +02:00
Thijs Wiefferink 395cc6de07 Fix usage of 'resale' in 'default.yml' for 'flagProfile' section
- 'resale' was used instead of 'resell' (as defined in GeneralRegion#RegionState) in the 'flagProfile' section, causing the flags not getting applied when the region is in reselling state.
- Added fallback to 'resale' section if 'resell' section is not present (to properly read old config.yml/default.yml files)
- Fixed usage of '%resaleprice%' in the resale greeting, should be '%resellprice%'
- Fixes #303, thanks electro2560 for the great bug report!
2017-04-20 15:26:26 +02:00
Thijs Wiefferink 3b9d6187ca Fix checkstyle fail 2017-04-17 21:34:32 +02:00
Thijs Wiefferink 9d1585f513 Fix groups file getting cleared on server start
- Fixes #299
- Because of an earlier change the groups file is loaded before regions are loaded on server start, and region groups remove themselves if there are no valid regions in them anymore.
- Keep groups even though they are empty (so that configuration done in the group is not lost)
2017-04-17 21:32:15 +02:00
Thijs Wiefferink 9d6955039a Fix '/as groupdel' with non-existing group creating an empty one 2017-04-17 21:26:24 +02:00
Thijs Wiefferink 747b47057b Allow # in region name for /as stack to determine counter position 2017-04-11 21:22:35 +02:00
Thijs Wiefferink a973e254e6 Fix '/as addfriend' not allowing you to add players that are playing for the first time
- Fixes #297
2017-04-02 22:34:02 +02:00
Thijs Wiefferink a5105af3ad Add 'use' flag to default.yml again since people mess it up 2017-03-29 20:18:14 +02:00
Thijs Wiefferink 0bb0a05b76 Cleanup checkstyle from pom.xml in AreaShop module 2017-03-29 20:17:42 +02:00
Thijs Wiefferink dad502ec0c Add checkstyle to enforce formatting, change all formatting to comply 2017-03-29 20:15:44 +02:00
Thijs Wiefferink f471b9bbf0 Don't show 'in advance renting:' in '/as info' if maxExtends is zero
- Thanks to R0bstar for noticing this weird weird message combination
2017-03-09 16:14:30 +01:00
Thijs Wiefferink f69d1c41e6 Code cleanup and stricter visibility of methods/variables 2017-03-09 16:01:36 +01:00
Thijs Wiefferink 4ea6f59c49 Remove GeneralRegion#is{Rent|Buy}Region()
- It served no purpose and prevents IDEs from detecting type safety
2017-03-09 15:29:01 +01:00
Thijs Wiefferink 0b7158290f Add some more bStats statistics 2017-03-09 15:09:05 +01:00
Thijs Wiefferink e6757d23de Add bStats analytics
- Add bStats analytics because MCStats is down constantly
- Add custom graphs:
  - Language pie chart
  - Number of registered regions
  - Number of rental regions
  - Number of buy regions
- Closes #287
- In the future MCStats can be removed, for now I would like to keep complete data there for the times it does work
- Could add more graphs in the future for number of friends and things like that
2017-03-02 18:14:07 +01:00
Thijs Wiefferink 7cda35f4da Remove duplicate link in the readme 2017-02-12 20:04:35 +01:00
Thijs Wiefferink ee293d14b9 Fix link to CI in the readme 2017-02-12 20:03:46 +01:00
Thijs Wiefferink 2e0fce4955 Update repository url 2017-02-09 14:59:53 +01:00
Thijs Wiefferink 7afdefc9ed Add missing javadoc to loadFiles methods 2017-02-02 23:03:55 +01:00
Thijs Wiefferink 11f80e7ed1 Start using InteractiveMessenger
- Messaging functionality has been split into the InteractiveMessenger project: https://github.com/NLthijs48/InteractiveMessenger
- Jenkins build server has been changed to publish a Maven repository: http://jenkins.wiefferink.me/plugin/repository/everything
2017-02-02 22:59:00 +01:00
Thijs Wiefferink 40d45c7786 Fix using landlordName setting without using landlord (uuid) setting 2017-02-02 17:20:26 +01:00
Thijs Wiefferink 6b8e161e43 Ensure buy/rent/resell price is never below zero
This prevents problems with negative payment or withdrawal in Vault if input validation of a command is not good enough or if a price has manually been set below zero.
2017-02-02 17:18:26 +01:00
Thijs Wiefferink e1b2f7391c Improve message when you cannot rent/buy a region
The message did not specify which region cannot be rented/bought, which has now been added.
2017-02-02 16:45:15 +01:00
leNic 89ae8b9b4a Fixed reselling with negative prices (#280)
Prevents setting a negative resell price,. Some economy plugins accept a withdraw with a negative number, which has bad consequences (for example EssentialsEco does not accept it).
2017-01-28 20:25:24 +01:00
Thijs Wiefferink fab415bf19 Speed up expiration and expireWarning tasks
The expire task was triggering more often than the expireWarning task, causing lost warnings when warnings with a low time are specified
2017-01-23 14:26:25 +01:00
Thijs Wiefferink c7aa92be81 Indicate in default.yml that expressions can be used for region prices 2017-01-13 19:25:31 +01:00
Thijs Wiefferink 705c8d6891 Update README.md 2017-01-13 18:42:04 +01:00
Thijs Wiefferink 429d87c9ff Improve feature list 2017-01-13 18:41:16 +01:00
Thijs Wiefferink 1fdd8b32cc Add prices depending on a formula
- Price can be specified with an expression (JavaScript syntax)
- You can also use a block of JavaScript code, the value of the last line is used as result (for more complex logic)
- Supported settings: rent.price, buy.price, rent.moneyBack, buy.moneyBack (need more? ask me)
- Before evaluating the expression all region variables as defined in the config.yml file will be replaced (allows you to use %width% etc)
- Added %timesExtended% variable for use in expressions (to know how long the user is renting for)
- '/as setprice' and signs still only allow number input to prevent security problems (this means actual config access is required to do anything of harm with JavaScript)
- Closes #23
2017-01-13 16:56:02 +01:00
Thijs Wiefferink 7900f78a8c Change default WorldGuard flags to include block-place and block-break
Way too many people set the block-break and block-place flags on bigger or even the global region to deny (which is unnecessary and wrong relatively, for global use 'passthrough: deny' instead) so this patches up those mistakes by setting them at the AreaShop region
2017-01-13 16:06:18 +01:00
Thijs Wiefferink 3a65a88849 Fix replacing variables into language variables
- Previously it would insert it as a message, causing the language variable to be split up into multiple parts (which prevents recognizing it later)
- If a Message is marked as inline with Message#inline() it will be inserted without breaking up the message
2016-12-27 16:17:04 +01:00
Thijs Wiefferink 7b491d0389 Lazily instantiate feature classes to improve performance 2016-12-27 16:15:17 +01:00
Thijs Wiefferink fd02c51492 Add setting to prevent cross-world teleportation with '/as find'
- If a region is in another world and 'findCrossWorld' is off, it will be filtered from the results
- 'teleportCrossWorld' will not be checked anymore if the teleport is called from '/as find'
- Resolves  #234
2016-12-26 23:29:40 +01:00
Thijs Wiefferink bb1f592807 Add setting to prevent cross-world teleportation with '/as tp'
Related to #234
2016-12-26 23:20:12 +01:00
Thijs Wiefferink 16c7a044ea Add and make use of escaping in messages
- Add escaping support to FancyMessageFormat: put a backslash before a tag and it will not be interpreted, also works for color codes (&2 and §2) and variables
- Make use of escaping in the Message class to properly handle user input as plaintext (previously user input that got printed back also got interpreted, like colors apply to it)
- All replacements given to Message are escaped, unless you wrap them in a Message before it.
- Replacement limits and infinite replacing detection have changed slightly
2016-12-26 22:56:35 +01:00
Thijs Wiefferink 152f183670 Fix region update after /as reload, cleanup unused code 2016-12-25 23:02:23 +01:00
Thijs Wiefferink 09b6e4c584 Fix string setting as profile in default.yml
- This has been broken in b525c5902c
- Fixes #267
2016-12-25 22:40:11 +01:00
Thijs Wiefferink aeb70196a3 Fix shutdown exception in SignsFeature 2016-12-24 19:59:04 +01:00
Thijs Wiefferink 62148ea577 Move teleportation code to a feature class 2016-12-23 23:25:41 +01:00
Thijs Wiefferink fcc9fb0945 Refactor to introduce Manager and RegionFeature
- Manager to serve as abstract class for managers (like FileManager), implements a lifecycle to allow for shutdown operations (like save all files)
- RegionFeature to server as abstract class for region features
- Improve instantiation and lifecycle of features (global features and region specific ones)
- This is preparation for moving more region functionality into feature specific classes (which makes GeneralRegion smaller and easier to maintain)
2016-12-23 16:03:22 +01:00
Thijs Wiefferink b525c5902c Fix default settings leaking when getting configuration sections
- Default settings and custom settings are in separate YamlConfiguration instances now to prevent leaking
- When getting a configuration section you now know that either it is from the current default.yml file or the default.yml file in the jar (querying settings from the section will always have the same source)
- Fixed a startup null pointer
- Fixed #266
2016-12-23 14:07:26 +01:00
Thijs Wiefferink b18a7cc6d5 Fix [break] in hover lines
Hover lines are still a bit broken when trying to insert complex messages into them, this is hard to do in a proper way though.
2016-12-10 15:19:34 +01:00
Thijs Wiefferink 54b6e84558 File loading improvements to be more robust 2016-12-04 21:14:31 +01:00
Thijs Wiefferink bae3c0a199 Ask for config files in the issue template 2016-12-04 17:56:37 +01:00
Very Evil Olaf 508270a280 Update ISSUE_TEMPLATE.md (#258)
Note that 'latest' is not a correct version
2016-12-04 17:48:36 +01:00
Thijs Wiefferink 87b2cb9ecd Prevent exceptions if a schematicProfile does not exist 2016-12-04 17:31:22 +01:00
Thijs Wiefferink 271b17b6be Set version to 2.4.0 and update language files 2016-12-02 14:37:27 +01:00
Desjardins Jérôme 1dfedea50c Create a permission for teleporting to available regions (#241)
* Update GeneralRegion.java
Add Available abstract function
Check Permission modification

Update BuyRegion.java
Add Available function for selled

Update RentRegion.java
Add Available function for rented

Update TeleportCommand.java
Check new permission

Finish feature teleport available region

* Fix translation
2016-11-19 17:15:23 +01:00
Thijs Wiefferink d9abe2e347 FIx problem with null regionFlags sections 2016-11-14 18:02:59 +01:00
Thijs Wiefferink 1ba2e21ae9 Make profile based settings easier to understand
- Remove 'signProfiles', 'flagProfiles', 'eventCommandProfiles', 'schematicProfiles' and 'expirationWarningProfiles' from the config.yml file
- Add the removed profile contents directly to the setting without the trailing 's' in the default.yml file (this prevents the need to understand the creation of profiles, and then assigning them, taking out a step in the thought process of users)
- Added method in GeneralRegion to get a ConfigurationSection from the region file, group files or default file while also taking into account the translation from a string to a profile that is defined in the config.yml file. This ensures backwards compatibility with current config files (the old style will not be promoted anymore though).
- The 'expirationWarningProfiles' does not have the subkeys 'warnPlayer' and 'commands' anymore, it is just a list of commands now, using the '/areashop message' command to warn a player.
- Add a workaround for the empty sign problem after unrent/sell of a region while having restore enabled, an AsyncWorldEdit plugin installed and signs inside the region (sign will be updated again half a second after unrent/sell).
2016-11-13 00:44:35 +01:00
Thijs Wiefferink fcdfdc6094 Update language files
- Swedish is added
- German, French and Russian are improved
2016-11-07 14:13:03 +01:00
Thijs Wiefferink 8a7e2ba5c2 Indicate limits when a MaxChangedBlocksException is thrown by WorldEdit 2016-11-07 13:52:54 +01:00
Thijs Wiefferink 0950452692 Fix a couple of problems caused by vertical /as stack addition 2016-10-31 21:07:08 +01:00
Thijs Wiefferink 293978f068 Decouple Message class from replacement providers
- Instead of applying replacements by testing for a replacement that has the GeneralRegion type, it now checks for a ReplacementProvider instances (one step closer to making Message independent of AreaShop).
- Replacements are handled one by one with a switch-case instead of getting them from a map, helps performance a lot.
2016-10-25 20:57:58 +02:00
Thijs Wiefferink 5efe14b8e9 Add up and down direction for '/as stack'
Prevents creating regions above and below the world limits, still needs
testing.
Progress for #105
2016-10-24 15:02:49 +02:00
Thijs Wiefferink 839d510151 Switch from Bukkit to Spigot Maven repo since it is down
Also switched from Bukkit 1.7.9 to Bukkit 1.8.0 because that is the lowest version available on the Spigot repo
2016-10-17 23:45:08 +02:00
Thijs Wiefferink 9180d9b8ee Fix small language file issue
When you only have a formatting code before a language variable, the hover/click effects will accidentally be applied to one text part earlier
2016-10-16 18:29:26 +02:00
Thijs Wiefferink 7aa786f4ce Fix default config trying to execute /as message as player
Fixes #221
2016-09-04 22:43:03 +02:00
Thijs Wiefferink 10ea8540e7 Add tab completion for '/as me [player]'
Closes #220
2016-09-04 00:59:04 +02:00
Thijs Wiefferink dba00769f6 Fix problem with line breaks 2016-09-03 20:58:45 +02:00
Thijs Wiefferink 44c70c6a33 Cleanup messages about region that does not exist in WorldGuard 2016-09-03 19:46:05 +02:00
Thijs Wiefferink 570f7b4055 Don't extend rent when using '/as setowner' to set a different owner
Also remove new owner from the friends list.
Fixes #219
2016-09-03 19:19:40 +02:00
Thijs Wiefferink feafa012dd Fix issue with \n on 1.7.x servers
- Each line of a message will now be sent separately instead of using '\n' in the text
- Drastically reduced the number of StringBuilders that are instantiated during message construction
- Fixes #222
2016-09-03 17:22:40 +02:00
Thijs Wiefferink 82b340ce1a Messages: also parse section signs into color tags properly
Fixes line-wrapping removing color in some cases
2016-09-02 21:43:58 +02:00
Thijs Wiefferink 93809f27fc Rename events to be consistent with commands
- AddFriendEvent -> AddedFriendEvent
- DeleteFriendEvent -> DeletedFriendEvent
- RemovedRegionEvent -> DeletedRegionEvent
2016-08-28 22:45:20 +02:00
Thijs Wiefferink f8ed3654fd Fix compilation error 2016-08-28 22:31:06 +02:00
Thijs Wiefferink 58a1afccf3 Invert inheritance of RegionEvent and CancellabelRegionEvent/NotifyRegionEvent 2016-08-28 22:29:45 +02:00
Thijs Wiefferink d9c3573225 Change RegionUpdateEvent to UpdateRegionEvent
This breaks plugins using the event
2016-08-28 22:21:33 +02:00
Thijs Wiefferink 1577443203 Generalize events better
Adds generic classes for events with a region (BuyRegion, RentRegion or GeneralRegion)
2016-08-28 22:11:17 +02:00
Thijs Wiefferink ab7a92c57d Update README.md 2016-08-26 19:49:21 +02:00
Thijs Wiefferink 2e09b0f60f Update README.md 2016-08-26 19:48:59 +02:00
Thijs Wiefferink 6e5c35f95b Add extension plugins section 2016-08-26 19:45:37 +02:00
Thijs Wiefferink 066ceedafd Add 'build' flag by default to prevent inheriting from parent regions. 2016-08-21 22:20:25 +02:00
Thijs Wiefferink c8ebe24bd3 Put break in '/as info' help message in the right spot 2016-08-19 20:52:07 +02:00
Thijs Wiefferink ad7db5ee23 Attempt to fix unable to add new players with '/as addfriend' 2016-08-16 22:43:09 +02:00
Thijs Wiefferink f80a8178ff Fix formatting not clearing on new lines 2016-08-13 22:28:15 +02:00
Thijs Wiefferink 05c8e1a7e4 Make loggin methods more generic 2016-08-10 16:07:39 +02:00
Thijs Wiefferink 9904805310 Improve version detection of WorldGuard
- First detect version 5
- Then detect lower than 6.1.3
- Else check build number:
  - Build number exists and lower than 1672: 6
  - Build number exists and Is 1672: broken
  - Else: 6_1_3
2016-08-09 22:56:21 +02:00
Thijs Wiefferink 0df2f429c0 Only print build number warning if we found it 2016-08-09 22:38:33 +02:00
Thijs Wiefferink b3408a2648 Fix compilation error and WorldGuard version detection 2016-08-09 21:52:53 +02:00
Thijs Wiefferink e1f89e7904 Cleanup some leftover logging in an old style 2016-08-08 22:06:31 +02:00
Thijs Wiefferink 064b129205 Change version to 2.3.2 and update languages
- Russian has been added
- Spelling errors in French have been corrected
2016-08-07 22:21:57 +02:00
Thijs Wiefferink 8111387f32 Improve friend line of /as me, add click hint
Change blue color of hover popup to gold, which will be used as action color
2016-08-07 22:06:09 +02:00
Thijs Wiefferink a4b23bebba Improve line of rented regions in info command 2016-08-07 21:49:44 +02:00
Thijs Wiefferink 7421e685fa Improve robustness of variable replacing in messages
- Once the limit is reached the argument replacer would still continue sometimes (if a the replacement itself triggers the limit and the inserted message increases the size of the message we are building and adds a parameter tag again, like %0%)
- The language tag replacer also stops earlier now, it did not have the above problem though
- Fixed FancyMessageFormat.insertMessage() not checking its parameters
- Message.get() with a limit will now return an empty message if the limit is reached to prevent problems like above.
- Closes #205
2016-08-07 00:09:30 +02:00
Christoph Krüger @Androkai 374b68d8fa Update VaultAPI-repo (#206)
The url of the Vault Maven repository has changed.
2016-08-06 22:36:26 +02:00
Thijs Wiefferink ca7a9664f3 Fix error in info command of rental region 2016-08-02 22:27:55 +02:00
Thijs Wiefferink e957b4fc73 Remove all reflection for sending fancy messages
- Reflection removed
- JSON is now fully escaped instead of lenient escaping
- Sending is now done with /tellraw
2016-08-01 21:31:14 +02:00
Thijs Wiefferink 6493bc4f78 Add empty lines if a page does not fill the screen
Relevant for commands like `/as info all` that can have pages
2016-08-01 21:28:11 +02:00
Thijs Wiefferink 2db1b6a243 Prevent updater throwing errors sometimes when BukkitDev is offline 2016-08-01 20:46:40 +02:00
Thijs Wiefferink 864662a3c4 Add javadocs to limitgroup inner class and setting methods 2016-08-01 20:23:49 +02:00
Thijs Wiefferink 59b960b87c Update languages, set version number to 2.3.1
- Added German translation
- Added French translation
- Added Norwegian translation
2016-08-01 19:36:50 +02:00
Thijs Wiefferink 2de653d73f Add automatic conversion of language files downloaded from Transifex 2016-08-01 18:03:09 +02:00
Thijs Wiefferink 4feee59834 Cleanup info and warning messages. 2016-08-01 16:18:05 +02:00
Thijs Wiefferink 816d136a62 Change version number to 2.3.0, update languages
- Only English and Dutch are available yet
2016-07-24 21:48:39 +02:00
Thijs Wiefferink 121de7dc7e Add build number option to Maven
- Build number option can be used by Jenkins to add the build number
- Build number of soruce on Github will be #CUSTOM to mark custom builds
- Release versions will not contain a build number
- Closes #185
2016-07-24 20:59:25 +02:00
Thijs Wiefferink f7c86881cc Fix the default flagProfiles settings, fix migration issues. 2016-07-24 20:25:58 +02:00
Thijs Wiefferink 351d51b664 Correct message for reselling region entries. 2016-07-23 19:31:45 +02:00
Thijs Wiefferink 5a28476cf0 Add better limits for messages
- Recursive replacements are handled by catching stackoverflow exceptions
- Messages are limited 30000 in length for the produced JSON string since the client cannot handle more
- Error message print out the message key and start of the message
2016-07-23 17:21:08 +02:00
Thijs Wiefferink 8143bdae27 Add pages to the /as info command to prevent crashes
- Output displayed in pages of 18 (+ header and footer it fills the max of 20 you can see without scrolling)
- Footer shows current and max page, and has buttons to go to next/previous
- Commands accept [group] [page] both as optional arguments, works because page is a number (number as group would be weird)
- Entries show basic info about regions (owner/price/duration), and of course can be clicked to show all info
- Made debug command more generic
- Closes #172
2016-07-23 02:57:31 +02:00
Thijs Wiefferink b62744fe10 Add warnings for missing settings in limit groups.
Closes #164
2016-07-21 23:00:19 +02:00
Thijs Wiefferink fe0b63c760 Remove incorrect check 2016-07-17 23:51:24 +02:00
Thijs Wiefferink def774c7a1 Link javadoc of external classes properly
Classes of Bukkit, WorldGuard and WorldEdit that appear in the javadoc now link to the javadoc of them.
2016-06-27 23:38:44 +02:00
Thijs Wiefferink 7c5cb5f5aa Add javadoc to getApplicableRegions methods 2016-06-27 23:16:21 +02:00
Thijs Wiefferink 8af6e1d6f1 Fix small Maven warning 2016-06-25 22:20:21 +02:00
Thijs Wiefferink e0e6c39dae Fix WorldGuard version detection for later stable releases 2016-06-21 22:42:56 +02:00
Thijs Wiefferink dabe46bd47 Move all sign related methods into SignsFeature
- Each GeneralRegion now has a SignsFeature
- Each SignsFeature contains RegionSign instances representing the actual signs
 - The RegionSign class contains methods to update them etc
 - There is one SignsFeature that is not linked to a region, but registered as listener to update the signs at events
2016-06-20 20:16:13 +02:00
Thijs Wiefferink ec478a05d1 Move region friends code to separate Feature class 2016-06-20 18:22:35 +02:00
Thijs Wiefferink e21c0aafde Add events for adding/removing friends
- Cancellable event for adding friends: AddFriendEvent (region, friend and who is trying to add it available)
- Cancellable event for removing friends: DeleteFriendEvent (region, friend and who is trying to delete it available)
- Closes #54
2016-06-20 17:03:12 +02:00
Thijs Wiefferink 52bf88f4a5 Prevent RemovedRegionEvent triggering twice
Add debug logging for RemovedRegionEvent and AddedRegionEvent
2016-06-20 16:32:10 +02:00
Thijs Wiefferink e4de560a65 Prevent Maven warning
It was trying to include the WorldGuard6 handler class twice in the jar file
2016-06-20 16:28:23 +02:00
Thijs Wiefferink 6481da29e4 Add compatibility for WorldGuard build 1674 and up.
- Added a module for WorldGuard 6.1.3 to adapt to changes in flag related methods.
- No compatibility with build 1672, since there is no dependency in the Maven repo of WorldGuard to target this (this is a dev build though so I don't expect people using it long-term)
- Move properties for setting Java version to the parent pom file (other modules inherit them)
- Move repositories to the parent pom file (other modules inherit them)
- Fix AreaShop module not declaring its parent
- Fixes #170
2016-06-18 23:23:22 +02:00
Thijs Wiefferink f287cc91a6 Remove leftover logging 2016-06-13 21:11:00 +02:00
Thijs Wiefferink 95b7b50346 Add development builds and javadocs links 2016-06-13 20:59:08 +02:00
Thijs Wiefferink 21db2ff440 Improve Maven setup for javadoc and source
- Generate a .jar file with the sources if -Dsources is provided
- Generate javadocs if -Djavadoc=/path/to/destination is provided
- Copy final .jar file to directory if -DcopyResult=/path/to/server is provided
- Adding missing javadoc comments
2016-06-13 20:36:17 +02:00
Thijs Wiefferink 36dd978a92 Cleanup the config file and settings
- Moved scheduled task settings to hiddenConfig.yml (settings that are not visible, but still usable)
- Remove 'postCommandErrors' setting
- Also execute commands defined in 'expirationWarningProfiles' when player is not online
- Move around settings in config.yml and improve explanations
- Closes #168
2016-06-13 17:03:20 +02:00
Thijs Wiefferink 6cc3f2a52f Combine all messages about region not registered
And replace mentions of 'this region' with the actual region name.
2016-06-13 14:47:10 +02:00
Thijs Wiefferink 852731b1ad Add action confirmations when using signs
- Confirmations by default for selling/unrenting by signs, not for renting/buying
- Fixed a bug with message composing which would duplicate hover/click parts.
- Added `/as message <player> <message...>` for internal/console use (not shown in help).
- Closes #50
2016-06-12 21:39:12 +02:00
Thijs Wiefferink 30faa77da9 Fix small error in multiple regions found message 2016-06-12 19:38:05 +02:00
Thijs Wiefferink ec57b922b8 Messages: Version fixes, fallback to plain.
- Properly parse NMS version number to support 1.10
- Fallback to plain messages if sending a fancy message breaks (we try again after restart/reload)
2016-06-12 16:48:47 +02:00
Thijs Wiefferink c2bcc6008b Add hover/click to some forgotten mentions of regions 2016-06-12 13:25:55 +02:00
Thijs Wiefferink 72a05bedce Merge personal/all help messages. 2016-06-11 22:40:09 +02:00
Thijs Wiefferink bc73a8b20d Cleanup links to issues 2016-06-11 17:35:00 +02:00
Thijs Wiefferink 832e8218b6 Add issue template for bugs/feature requests 2016-06-11 17:29:47 +02:00
Thijs Wiefferink 6fcb629133 Move to the me.wiefferink package
The nl.evolutioncoding domain is soon not mine anymore, and this new one I do intend on keeping.
2016-06-07 22:39:45 +02:00
Thijs Wiefferink 7d6a1f35c1 Messages: Add hover/click items to region info
- The hover/click parts only appear if you have permission to use the command linked to it
- Red crosses added next to the friends in the friend list to remove them
2016-06-05 17:04:38 +02:00
Thijs Wiefferink 60257d45c2 Messages: Add a bunch of click/hover actions to '/as info region <region>'
- rent/unrent/buy/sell/extend
- teleport, set teleport location
2016-06-04 22:46:10 +02:00
Thijs Wiefferink 2300227d87 Messages: Fix problem with message insertion sometimes missing leftover part 2016-06-04 20:57:14 +02:00
Thijs Wiefferink b1852b10bb Improve /as me, remove /as info player
And change underline to bold for clickable things (underline leaks through in the next line, giving annoying layout issues)
2016-06-02 22:39:30 +02:00
Thijs Wiefferink 88fdb0c3fc Add 'ALL' flagProfiles state that is always applied
And add block-break and block-place by default.
2016-05-31 22:36:18 +02:00
Christoph Krüger 491e55fc77 Change Vault dependency to Maven repo instead of .jar
Use the Maven repository of Vault instead of including a jar file in the repository.
2016-05-28 23:19:23 +02:00
Thijs Wiefferink c7b0a2c663 Let /as help respect the areashop.help permission
Closes #155
2016-05-28 17:04:06 +02:00
Thijs Wiefferink 868f4d6b58 Events: Add refunded money to UnrentedRegionEvent and SoldRegionEvent
Closes #147
2016-05-28 17:00:52 +02:00
Thijs Wiefferink 0d4b034181 Messages: Detect and stop replacement loops. 2016-05-28 16:51:32 +02:00
Thijs Wiefferink 5f20689ba3 Improve language variable argument detection 2016-05-27 21:01:14 +02:00
Thijs Wiefferink 38b658fccf Message changes: click on regions/players
- Click on region name for region details
- Click on player name for regions of the player
- Click on landlord name for regions of the landlord
- Change color codes to things like [blue] instead of &9 (both are supported though)
2016-05-24 23:18:25 +02:00
Thijs Wiefferink 28ed20c0b5 Message system fixes and improved robustness
Hover/click message for '/as info'
2016-05-23 12:16:19 +02:00
Thijs Wiefferink aaff36b2eb Add hover/click support for messages #18
- Language files support a way to add hover tooltips, click commands and click insert commands (using FancyMessageFormat created together with PhoenixIV)
- Language variables support arguments
- Help listing (/as help) uses the new hover/click things, more to come
- See #18 for the TODO list
2016-05-22 21:36:58 +02:00
Spidev46 49b536cab0 There is a mistake with the messages (#153)
Confirmation message of reselling a region does not go to the old owner.
2016-05-22 21:19:10 +02:00
Thijs Wiefferink 9a9969dea3 Fix problems with detecting most important region when placing a sign.
WorldGuard filters child regions from the ApplicableRegionSet for some reason, so setting parent/child relations on regions messes up the detection because the children can never be found.
2016-03-07 12:21:33 +01:00
Thijs Wiefferink 84e4b49bfd Update language files
English, Dutch and German are complete, others are only partially complete.
2016-03-06 00:07:31 +01:00
Thijs Wiefferink 6daaf6997d 1.9 compatibility fixes (getOnlinePlayers() method) 2016-03-05 22:15:21 +01:00
Thijs Wiefferink c445a62334 Add variable support to all messages where a region is known (mostly messages of commands were not using it yet). 2016-02-08 19:39:33 +01:00
Thijs Wiefferink 0d205b0d9e Change general.teleportLocationY to also accept a number. 2016-02-08 14:43:24 +01:00
Thijs Wiefferink 8c33826c2c Add build flag to default flagprofiles, users are often having trouble with this 2016-01-26 22:35:01 +01:00
Thijs Wiefferink 51e1dbafb7 Fix running sign commands going wrong.
Player commands are run first, which normally rents/buys a region, so when the console commands are ran after that, then it will run the commands of the wrong state (since the state just changed). Also fixed a minor WorldGuard version dependency issue.
2016-01-26 22:20:45 +01:00
Thijs Wiefferink 6edad3faff Add priority and interact flag to config.yml by default
50% of the issues are having more regions at the same place, and therefore requiring a higher priority for the AreaShop region and having chests accessible by anyone instead of only the region owner/member. This should fix these problems.
2016-01-12 21:43:04 +01:00
Thijs Wiefferink f89e0f861b Add a link to a preview server 2016-01-08 20:18:47 +01:00
Thijs Wiefferink 770b1d98df Refactoring:
- Move a bunch of utility methods from the AreaShop class to Utils
- Comments styling cleanup
- Display warning in console when region file does not load correctly (is empty)
2016-01-05 22:31:55 +01:00
Thijs Wiefferink 8e5baa47af Fix variables of sell messages 2015-12-26 20:08:01 +01:00
Thijs Wiefferink 367466735e Fix the 'n:<name>' option for member/owner region flags
Before it would keep the 'n:' part when adding the name to the region, therefore adding an incorrect name.
2015-12-26 00:45:05 +01:00
Thijs Wiefferink ade6bc3971 Add AddedRegionEvent+RemovedRegionEvent, moved sign/flags updating
- Sign updating now uses the event system
- WorldGuard region flag updating now uses the event system
- After changes made by commands/other user input it will now use update() on the region instead of the sign and region flag commands.
2015-12-13 19:55:47 +01:00
Thijs Wiefferink 05fd8c0156 Implement event system
- 'ask' type events that can be cancelled, broadcasted before the action happens
- 'notify' type events that cannot be cancelled, but only let you know that it has happened
- Events for renting (with extending flag), unrenting, buying, selling, reselling
- General 'RegionUpdateEvent' to listen to as display service (update signs, update regions flags, etc)

All messages in the GeneralRegion, RentRegion and BuyRegion classes can now use all region variables (in the future all other messages will also be worked through)

Closes #84
Closes #86
2015-12-11 20:54:12 +01:00
Thijs Wiefferink 5403472476 Cleanup/update config.yml and default.yml comments
- Add links to the wiki.
- Make things more consistent.
2015-12-10 23:16:19 +01:00
Thijs Wiefferink c4ee7bc7aa Add 'areashop.linksigns' to the 'areashop.*' permission group 2015-11-24 20:59:58 +01:00
Thijs Wiefferink 940f1969b6 Add link to dev builds on Jenkins 2015-11-24 20:43:44 +01:00
Thijs Wiefferink 07eb5477b8 Update Metrics 2015-11-17 21:21:27 +01:00
Thijs Wiefferink a4112092b5 Fix inclusion of the version specific classes of WorldGuard/WorldEdit in the final jar 2015-11-15 23:47:23 +01:00
Thijs Wiefferink 872d81b0a9 Cleanup code, fix some small bugs
Most of these things have been found with help of Intellij IDEA, preferring it over Eclipse already
2015-11-15 23:35:48 +01:00
Thijs Wiefferink b04871c553 Add rental to max when rental would go above maxRentTime otherwise
- Setting `extendToFullWhenAboveMaxRentTime` to set if AreaShop should
automatically extend to max when the player cannot rent a full duration
because of `maxRentTime`.

Fixes #94
2015-11-11 11:56:16 +01:00
Thijs Wiefferink fd1b8fba4c Fix inactiveSetting debug messages
The messages still assumed the inactiveSettings was in minutes instead
of in milliseconds.
2015-11-02 22:39:40 +01:00
Thijs Wiefferink 991e7b1961 Fix lastActive sometimes not updating correctly
- Update the lastActive time at rent/buy to ensure it is non-zero
- Ignore lastActive time of zero, give back current time
- Update lastActive time at server shutdown for players that are still
online, quit events are not fired at shutdown
2015-11-02 22:32:51 +01:00
Thijs Wiefferink aac963325a CI run :) 2015-11-01 23:03:41 +01:00
Thijs Wiefferink 3e7c7ce76b Fix message variables for '/as info player <player>' feedback 2015-10-31 23:15:11 +01:00
Thijs Wiefferink c858d30481 Add .gitignore to the repository 2015-10-19 19:07:31 +02:00
Thijs Wiefferink b090fd5577 Remove MCStats image, site is more offline than online 2015-10-17 22:10:38 +02:00
Thijs Wiefferink 8d132c66c4 Prepare for the v2.2.1 release
- Update version number
- Update language files from Transifex
2015-10-17 21:03:30 +02:00
Thijs Wiefferink 50e3e59543 Fix indentation and error message of WorldEdit 6 integration handler 2015-10-15 12:13:15 +02:00
Thijs Wiefferink eb21b9567e Change signtags from [arent] and [abuy] to [asrent] and [asbuy]
Changes #45
2015-10-08 22:49:41 +02:00
Thijs Wiefferink 4dba305f6d Change the default sign tags to something more specific
Note: Change documentation pages to include this.

Fixes #45
2015-10-06 22:41:59 +02:00
Thijs Wiefferink 7481d8287f Retrieve money from landlords when unrenting/selling a region.
Prevents exploits by giving money to landlords, and then
unrenting/selling to get money back from 'the server' (nobody). Now it
will get the money back from the landlord, or if that is not possible
then not give anything back.

Fixes #75
2015-10-06 22:15:09 +02:00
Thijs Wiefferink 4d41decbe5 Config part of week indicators 2015-10-03 21:14:24 +02:00
Thijs Wiefferink 7fc5a5af81 Add weeks time indicators, clean other indicators
The old Dutch time indicators have been removed from the lists, this
might cause problems for people if they regenerate their config but
don't add these tags again.

Added console warnings at startup to indicate incorrect duration
strings.

Fixes #32
2015-10-03 21:12:38 +02:00
Thijs Wiefferink d26fa99b95 Fix using the seconds modifier with /as setduration
AreaShop could correctly read and use all seconds modifiers that are
defined in the config, but the `/as setduration` command would not
accept it as input.

Fixes #82
2015-10-03 20:38:38 +02:00
Thijs Wiefferink 39d755d2db Make removing regions from AreaShop less destructible for region flags
First AreaShop would reset all flags, now it will only reset the
greeting and farewell flags. This is to make sure players do not get
confused about the region, if the greeting is still there then players
might think it is still connected to AreaShop.

Fixes #72
2015-10-03 20:27:19 +02:00
Thijs Wiefferink 48ab46ecf7 Fix indirect breaking of signs causing it to disconnect
If you would break a block behind/below a sign AreaShop would disconnect
it from the region, which is most of the times not the wanted behaviour.
This commit changes it to simply leave a floating sign there, so that it
is still visible and not disconnected from the region.

Fixes #15
2015-10-03 20:10:44 +02:00
Thijs Wiefferink b3fa31e1cc Remove debug message 2015-10-02 20:44:25 +02:00
Thijs Wiefferink 783085fbf7 Cache region variable replacements 2015-10-02 20:41:00 +02:00
Thijs Wiefferink aa093b0c8a Fix sign clicking still executing while event is cancelled. 2015-09-26 01:06:22 +02:00
Thijs Wiefferink 9c357fe929 Remove lastActive from region file when unrented/sold
No problems if it is there, but just keeping the region file clean.
2015-09-11 22:44:12 +02:00
Thijs Wiefferink 4d70571a23 Improve failed file loading
- Detects incorrectly loaded config.yml and default.yml
(YamlConfiguration prints errors to console and continues silently,
returning an empty configuration if something is wrong normally)
- Will go into error state when loading fails
- Improved some error handling to make sure that no extra errors are
thrown because of trying to close non-existing streams.
2015-09-10 21:58:57 +02:00
Thijs Wiefferink 29a4105ece Add Vault to the repo to make it easier to compile 2015-09-06 17:05:38 +02:00
Thijs Wiefferink edc7136063 Fix '/as info' always showing landlord line
It would always show the landlord line, if there was no actual landlord
it would show '<UNKNOWN>' as name, which is very confusing.

Fixes #46
2015-09-06 16:42:16 +02:00
Thijs Wiefferink 6fabc75be4 Fix '/as info' trying to filter by group too much
'/as info region' would also try to filter by group using the region
name, which would almost always cause an error message (group not found)
2015-09-06 16:38:23 +02:00
Thijs Wiefferink 085507bf8b Add required dependencies section 2015-08-30 00:10:12 +02:00
Thijs Wiefferink 73ed3366ae Update README.md 2015-08-29 22:27:14 +02:00
Thijs Wiefferink 9ca029176d Fix '/as find' not getting your balance correctly
- If you search with your balance (and do not give a maxprice) it would
always use 0.0 as your balance, therefore not finding any regions.
- Also fixes the incorrect feedback, it would say it searched with a
maxprice instead of your balance and the other way around if no regions
are found.
- Fixed maxprice and balance display to use correct currency symbols and
layouts (decimals, metric prefixes, separator).

Fixes #59
2015-08-29 20:06:16 +02:00
Thijs Wiefferink bf181d69d7 Update README.md 2015-08-29 19:46:05 +02:00
Thijs Wiefferink 68c57515da Update README.md 2015-08-29 19:44:54 +02:00
Thijs Wiefferink 903d6c309f Update README.md 2015-08-29 19:44:39 +02:00
Thijs Wiefferink 0a02eb3254 Update README.md 2015-08-29 19:42:57 +02:00
Thijs Wiefferink bf04589fab Merge links to issues with the top menu 2015-08-29 19:42:11 +02:00
Thijs Wiefferink 14dd094803 Update README.md 2015-08-27 22:51:49 +02:00
Thijs Wiefferink 02df35304c Update README.md 2015-08-27 22:48:11 +02:00
Thijs Wiefferink 4321667ec5 Merge branch 'master' of https://github.com/NLthijs48/AreaShop 2015-08-26 20:05:03 +02:00
Thijs Wiefferink 5cf5df78c8 Add permissions to prevent buying resell regions
- Permission 'areashop.buynormal' can be negated to only allow buying
regions that are in resell mode
- Permission 'areashop.buyresell' can be negated to only allow buying
regions that are not in resell mode

This change does not affect existing permissions setups (above
permissions are true by default)
2015-08-26 20:04:50 +02:00
Thijs Wiefferink 8608d6ce1d Update README.md 2015-08-25 17:40:08 +02:00
Thijs Wiefferink 614336862e Update README.md 2015-08-25 17:38:02 +02:00
Thijs Wiefferink a4ea175f1b Update README.md 2015-08-25 17:33:52 +02:00
Thijs Wiefferink c96043aa38 Update README.md 2015-08-25 17:30:11 +02:00
Thijs Wiefferink d5a29f6c32 Update README.MD: WIP frontpage
Frontpage like the BukkitDev and Spigot Resources section.
2015-08-25 17:29:21 +02:00
Thijs Wiefferink 5176a1c2c5 Update README.md 2015-08-21 21:45:42 +02:00
Thijs Wiefferink 89569ea182 Update README.md 2015-08-17 23:11:46 +02:00
Thijs Wiefferink f349657a59 Fix bug with teleporting to signs
Fixes #47
2015-08-13 22:04:22 +02:00
Thijs Wiefferink 40d3d4d8af Add group filtering to /as info <rented|forrent|sold|forsale>
- Filter regions by group for the mentioned subcommands of /as info
- Clean/refactor code
- Sort the output
- Add Comparable, equals() and toString() to GeneralRegion

Closes #44
2015-08-11 22:41:30 +02:00
Thijs Wiefferink 0d5db8fa4e Add option to deny extending when over rent/total limits
Turned on by default, added config setting
'allowRegionExtendsWhenAboveLimits' to disable this change. Normally
this is expected behaviour, which pushes users to let the region run out
if they should not be able to rent it anymore (was impossible to do
before).

Closes #41
2015-08-10 21:43:29 +02:00
Thijs Wiefferink 25c56e8ecb Add permissions for landlords to remove regions
Closes #33
2015-07-31 22:56:12 +02:00
Thijs Wiefferink 9f436a7eb4 Fix landlord UUID/name handling
Also changes handling of buyer/renter UUIDs and names, if the playerdata
of a player is not available anymore AreaShop will still be able to
display his name. Also unrenting/selling will still properly pay back
the player through Vault (by name instead of UUID).

Fixes #35
2015-07-30 22:55:49 +02:00
Thijs Wiefferink f76c1b8a9f Save last online time self instead of using the Bukkit API
The Bukkit API returns an incorrect last online time when the player.dat
file is not present (for example when a server saves inventories etc.
somewhere else, or when it is cleaned).

Improves landlord handling when there is no UUID present in the config
files.

Closes #34
2015-07-28 23:02:52 +02:00
Thijs Wiefferink d466658f36 Allow only providing landlord name, instead of UUID 2015-07-28 21:50:28 +02:00
Thijs Wiefferink 04e02c4ce4 Adds a way to change number length for stack region names
Adds dots after all config explaination lines, fixes a couple things
with groups.yml file saving (would save unnecessary sometimes).

Fixes #26
2015-07-26 20:56:44 +02:00
Thijs Wiefferink 3bf493109c Add date/time variables for commands/schematics
Fixes #21
2015-07-26 20:15:45 +02:00
Thijs Wiefferink 2f9b6d3987 Update language files to the latest available versions on Transifex 2015-07-25 16:57:24 +02:00
Thijs Wiefferink 93d5612513 Fix a bug with depositing to players that never joined
Paying to players that never visited before will now fallback to using a
name instead of UUID towards Vault, which prevents problems (for players
that never visited, such as server accounts, you cannot get the name
from the UUID via Bukkit).
2015-07-25 16:56:41 +02:00
Thijs Wiefferink 937db4620d Fix problem with default value 'unlimited' for maxRentTime 2015-06-21 19:29:54 +02:00
Thijs Wiefferink a0239b8837 Fix loading when there is no regions folder 2015-06-21 17:08:11 +02:00
Thijs Wiefferink 401f52e687 Change additional places where the contains is used 2015-06-13 22:56:27 +02:00
Thijs Wiefferink 2f6874a16e Fix contains check for WorldGuard regions not version dependend 2015-06-13 22:50:06 +02:00
Thijs Wiefferink c95f4e1c6c Fix problem with '/as addfriend' denying first-joined players
Before it checked if the player had played before on the server in order
to check if the friend will get accepted, but this fails when the player
is playing for the first time. This has been repaired.
2015-06-13 22:06:34 +02:00
Thijs Wiefferink 1a2d755727 Fix message using incorrect time unit 2015-06-11 15:42:39 +02:00
Thijs Wiefferink c489e6eba4 Commit changes in language file 2015-06-11 15:32:29 +02:00
Thijs Wiefferink b1a56b5230 Fix maxRentTime, inactiveTimeUntilUnrent/-Sell settings
Made a misake while converting these settings to accept human-readable
durations strings instead of only minutes.
2015-06-11 14:11:41 +02:00
Thijs Wiefferink dfbc7805b5 Fix a couple of bugs 2015-06-11 00:51:44 +02:00
Thijs Wiefferink 8f2c95f5c4 Merge branch 'master' of https://github.com/NLthijs48/AreaShop 2015-05-22 19:01:40 +02:00
Thijs Wiefferink 0b9bffe68f Fix bug with changed time settings not loading old values 2015-05-22 19:01:30 +02:00
Thijs Wiefferink 7ac6e34c89 Update README.md 2015-05-12 10:25:07 +02:00
Thijs Wiefferink 5231f6e86e Change all time period settings to readable format
Changed all settings that took minutes or seconds as unit before to use
the format also used on signs (things like '50 seconds', '1 day', '3
months' etc).
Fixed a bug with display of currency numbers being unrounded when not
displayed with SI prefix.
2015-05-03 22:51:19 +02:00
Thijs Wiefferink 791b696aff Add support for Metric prefixes to display large numbers
Indications are used as defined on:
http://en.wikipedia.org/wiki/Metric_prefix, implemented from 'k' to 'Y'.
Added setting 'metricSuffixesAbove' to config.yml to specify from which
number these characters should be used.
Added setting 'decimalMark' to change the character(s) used as decimal
separation (is a comma instead of a dot in certain countries).
2015-05-03 00:15:05 +02:00
Thijs Wiefferink c92bc716dc Change module names to fit project setup
Forgot to rename the folders that contain the interface classes. Cleaned
pom.
2015-05-02 00:33:34 +02:00
Thijs Wiefferink 463b34e952 Merge pull request #13 from Androkai/patch-1
fix typo "targer" --> "target"
2015-05-01 11:02:53 +02:00
Androkai ff6e69196d fix typo "targer" --> "target" 2015-04-30 22:50:43 +02:00
Thijs Wiefferink 76ad952bb6 Remove unnecessary marking as 'to be saved'
Marking as 'to be saved' is already done when a setting change is
written to the YAML file, so it does not have to be called from the
places where settings are changed.
2015-04-28 20:38:44 +02:00
Thijs Wiefferink 0cdff5e143 Move README.md to the correct place. 2015-04-28 18:56:13 +02:00
Thijs Wiefferink 9dc3013215 Update README.md 2015-04-28 18:54:30 +02:00
Thijs Wiefferink 796b95c9f9 Change to a Maven project
Changed project layout to Maven, all dependencies except Vault (does not
have a maven repo) are now included in the pom.xml and will be
automatically downloaded by Maven when building. The project setup uses
modules to support both WorldGuard and WorldEdit version with 1 jar file
instead of having 2 files as the last versions of AreaShop had.

Small bug with boolean settings in the config files has been fixed.
Problem with '/as stack' stacking in the Y direction instead of Z has
been fixed. Plus some refactoring and small changes.
2015-04-28 18:53:42 +02:00
Thijs Wiefferink 2785a72457 Update README.md 2015-04-10 18:50:42 +02:00
Thijs Wiefferink c2df0cd912 Package and classes explanation 2015-04-10 18:47:20 +02:00
Thijs Wiefferink 4cd32a0792 Update README.md 2015-04-10 17:57:45 +02:00
Thijs Wiefferink 354e70af57 Add basic instructions for compiling AreaShop
Intructions to compile AreaShop from the source files provided here at GitHub.
2015-04-10 17:57:00 +02:00
Thijs Wiefferink fde60e2a27 Add permissions for landlords to add regions
Added things:
- "areashop.createrent.owner", "areashop.createrent.member",
"areashop.createbuy.owner" and "areashop.createbuy.member" to let
players add regions to AreaShop when they are member/owner of the
WorldGuard region (because they made the region for example).
- "areashop.setprice.landlord" to give landlords access to setting the
price for their regions
- "areashop.setduration.landlord" to give landlords access to setting
the duration for their regions
- When "default" or "reset" is given as price then the price will be
removed and therefore inherited from a group or default.yml
- When "default" or "reset" is given as duration then the duration will
be removed and therefore inherited from a group or default.yml
2015-03-17 21:22:57 +01:00
Thijs Wiefferink d1a3027e0b Update language files to the current status
Polish is back and 88% translated, Finnish is new and fully translated.
2015-03-13 21:16:44 +01:00
Thijs Wiefferink 4e57f03fc0 Added a command to set the landlord of a region.
The landlord receives all money from rents/buys of the region. Reselling
with '/as resell' does not transfer money to the landlord.
Unrenting/selling will not substract money from the account of the
landlord, so set the 'moneyBack' to 0 to prevent cheating. The
'landlord' setting is also present in the general section of
default.yml, so this means you can also add this setting to a region
group to easily make a group of regions give money to 1 player.
2015-03-13 21:07:59 +01:00
Thijs Wiefferink 83d4efc3a8 Remove redundant setting from the config to enable schematics
The 'enableSchematics' boolean setting from the config.yml file is not
usefull, 'enableRestore' in default.yml already handles the same thing,
and is more flexible (per region or region group instead of general)
2015-03-13 18:25:24 +01:00
Thijs Wiefferink 1395afffe9 Fix a bug with teleporting
Added messages when teleporting automatically changes to teleporting to
a sign instead of to the region or other way around.
2015-03-13 14:41:54 +01:00
Thijs Wiefferink 5094d39a96 Get worlds for WorldEdit the proper way (needs wrapped world) 2015-02-28 19:40:43 +01:00
Thijs Wiefferink e664c1efd9 Load regions at startup, check them at the first tick 2015-02-24 11:48:58 +01:00
Thijs Wiefferink 871eeed29c Change the loading of regions to all at once again
Otherwise it would cause problems with plugins that hook into AreaShop
and try to get regions.
2015-02-23 22:32:54 +01:00
Thijs Wiefferink 0d56762bfc Change to Vault integration to allow custom economies
AreaShop would not use an economy if it would be loaded after it.
2015-02-23 22:21:52 +01:00
Thijs Wiefferink c08763883f Fix a bug with '/as setowner' not saving the region file
Changed the way position the regions are marked as 'to be saved' to
prevent this problem in the future.
2015-02-23 21:48:57 +01:00
Thijs Wiefferink efb534f131 Fix the schematic saving 2015-02-23 19:26:20 +01:00
Thijs Wiefferink d9405a9f49 Make the updatechecker check async
If the updatechecker cannot reach BukkitDev it would slow down the
startup of the server up to 30 seconds (and also if you use /reload),
this will not happen anymore.
2015-02-23 18:11:51 +01:00
Thijs Wiefferink 684add89cd Change the way regions are loaded
Region loading is now started at the first server tick, and will do a
certain number of regions per tick ('loading.regionsPerTick' config
setting). This prevents problems with plugins that load worlds after
AreaShop is loaded. If AreaShop detects that a region does not have a
correct WorldGuard region assigned anymore or the world of the region is
not loaded it will be printed to the console, but it will not delete the
region anymore (which would lead to data loss).
2015-02-23 17:58:10 +01:00
Thijs Wiefferink d1848c0728 Delete .project 2015-02-23 13:32:04 +01:00
Thijs Wiefferink 9fd16290c0 Fix some unclear and wrong messages in the language file
Thanks to qlick for suggesting these language changes. Also fixes a bug
with the '/as info player' command, would cause an error if a region has
an incorrect UUID as owner or an UUID without name.
2015-02-22 23:16:37 +01:00
Thijs Wiefferink 3bbca11cc9 Added the '/as stack' command to easily create and register regions
/as stack <amount> <gap> <name> <rent|buy> [group]
    <amount> Number of regions that will be created
    <gap> Blocks distance between the regions
    <name> Name of the regions (number will be behind it)
    <rent|buy> The type of the region
    [group] A group to add the created regions to
    The regions will be created in the direction you are facing
2015-02-22 17:08:32 +01:00
Thijs Wiefferink b1be87014f Change schematic functions to new WorldGuard 6 classes 2015-02-19 17:22:06 +01:00
Thijs Wiefferink badcd77cfe Changing version number to get ready for a release.
Linksigns feature will be released next version together with other
setup tools.
2015-02-11 11:55:46 +01:00
Thijs Wiefferink 779d340bbb Fix translation of color codes for greeting/farewell messages
Ticket:
http://dev.bukkit.org/bukkit-plugins/regionbuyandrent/tickets/26-color-issue/
Thread at WorldGuard explaining the problem:
http://forum.enginehub.org/threads/color-codes-for-greeting-farewell-flags.15958/
2015-02-11 11:34:15 +01:00
Thijs Wiefferink 4e5061ba54 Added updating regions at plugin startup
Removed the '/as updaterents' and '/as updatebuys' commands, '/as
reload' also updates regions now.
2015-02-10 22:57:09 +01:00
Thijs Wiefferink b0f3bdc560 Fix the English language file
It got cleared by a faulty update script, I have some programs to get
the translated files from Transifix, and that also updates the header of
the English file but that went wrong and therefore it got cleared.
2015-02-10 12:31:21 +01:00
Thijs Wiefferink 5c9fdb6cc9 Added name change detection, updates regions when name is changed.
When a player logs in it will loop through regions owned by this players
and check if the saved playername is still the same as the current
playername and update the regionflags and -signs if necessary. Also
fixed some spelling mistakes in the English language file and updated to
the latest Transifex translations.
2015-02-09 23:46:32 +01:00
Thijs Wiefferink 23ea679cd9 Fixed a small bug with the permissions for the teleport command
The teleport command would refuse to teleport you if you only have
'areashop.teleportfriend' and/or 'areashop.teleportfriendsign'
permissions, while you should actually have access to those.
2015-02-03 22:55:31 +01:00
Thijs Wiefferink 58680c8cc4 Add a bulk sign linking mode for easier setup
When using '/as linksigns' you will get in sign linking mode. With
leftclick you can select a sign (max 100 blocks away) and with
rightclick you can select an AreaShop region (max 100 blocks away). If
you selected both then the sign will be linked to the region and then
you can select both again. This way you can easily link a lot of signs
to regions. Advice: Use WorldEdit or similar to get signs in front of
all regions (//stack), then use sign linking mode to link them all.
2015-01-30 12:12:00 +01:00
Thijs Wiefferink 75b752a235 Adds an option to '/as info' to list regions without group 2015-01-26 13:33:57 +01:00
Thijs Wiefferink fb51da84ae Fix a bug with teleporting to signs
If no signs are connected to the region it will now correctly teleport
to the location set by '/as settp' instead of always using the default
location.
2015-01-26 12:31:50 +01:00
Thijs Wiefferink 22d214e59d Add an option to set where '/as find' should teleport you to
Adds the 'findTeleportToSign' option in the general section of
default.yml, you can let it teleport to a sign or to the '/as settp'
location (if no location is set the default location is used)
2015-01-26 12:27:43 +01:00
Thijs Wiefferink 175b531eb5 Fix an unclear message when trying to create a sign for a region that is
already added to AreaShop.
2015-01-21 13:28:23 +01:00
Thijs Wiefferink 52591d3b6e Adds a blacklist of region that cannot be added
The blacklist consists of a list of regular expressions, by default the
'__global__' region is blocked because it is highly unlikely you want to
add that to AreaShop. The blacklist can for example be used to exclude
the spawn region while adding shops at spawn with the WorldEdit
selection of the '/as add' command.
2015-01-21 13:20:32 +01:00
Thijs Wiefferink 825074479c Cleanup 2015-01-18 16:58:33 +01:00
Thijs Wiefferink cc8cf1e560 Add proper punctuation to all languages (dots at the end) + more
Some preparations are made to later enable proper tab completion for
anyone instead of only OPs. Addfriend command only allows you to add
players that have played on the server before now.
2015-01-18 16:03:21 +01:00
Thijs Wiefferink a4169d127e Adds dots to all language strings and adds Chinese (Taiwan)
(All language files changed because I made a program to download them
all from Transifex and transform them to the format I want. Only
languages that are translated for 70% or more will be added to AreaShop)
2015-01-17 15:39:08 +01:00
Thijs Wiefferink 21340af89f Change the '/as find' command to randomly pick a region that suits
First searches all matching regions (rent/buy, maxprice and group), then
randomly picks one.
2015-01-12 21:55:01 +01:00
Thijs Wiefferink db06eae6c9 Add a message to show resell price when using '/as info region' 2015-01-12 21:42:54 +01:00
Thijs Wiefferink 5bae5ecf67 Fix a bug with buying a region while it is in resell mode 2015-01-12 17:11:08 +01:00
Thijs Wiefferink 679ffe2145 Releasing 1 version for WorldGuard 5.9 and one for 6.0+ now
The code represents the state of the WorldGuard 6.0+ version, the
uploaded version for 5.9 has some minor changes.
2015-01-07 12:01:04 +01:00
Thijs Wiefferink e6c5653073 Changes config version number, adds a file check for schematics 2015-01-06 22:35:08 +01:00
Thijs Wiefferink ea31dfdd65 Update languages (pulled from Transifex) and change version number 2015-01-06 22:03:23 +01:00
Thijs Wiefferink 9da31fed1f Restored compatibility with WorldGuard 5.9
AreaShop will detect if you use a 5.x version or something else, with
5.x it will add players to the regions by name, and otherwise by UUID.
AreaShop will always save UUID's itself, so future upgrading to higher
WorldGuard versions will be no problem.
2015-01-06 16:02:00 +01:00
Thijs Wiefferink 9baf0b7eec Adds an update checker and fixes some possible bugs
The update checker checks for updates at BukkitDev, if an update is
found it will print a message in the console and notifies OPs when
joining the server. It will never download files itself. The update
check can be switched off in the config. Also tried to fix a bug with
the /as me command, which could break when the friends lists is broken.
2015-01-06 11:46:02 +01:00
Thijs Wiefferink a14dc4e541 Fix a bug with the periodic updating of signs
If there is no sign connected to the region it would spam an error to
the console when the periodic update task runs.
2014-12-29 16:39:54 +01:00
Thijs Wiefferink 00d3256716 Fix a bug with inactive player unrent/sell settings
If the 'inactiveTimeUntilUnrent' or 'inactiveTimeUntilSell' settings
would be set to a value above 35000 it would cause an integer overflow,
resulting in a 50% chance that all regions will be unrentend/sold (and
if that does not happen it will still sell/unrent them too early). This
is caused by an integer overflow, switching to long fixed this problem.
2014-12-18 16:21:07 +01:00
Thijs Wiefferink 40338b66df Fix a bug with the '/as settp' command not accepting arguments
The command would always try to detect regions at the location you are
standing and would not consider the region argument.
2014-12-16 20:21:33 +01:00
Thijs Wiefferink 715bbfd9e3 Fix a bug where regions would not update after added to a group
Also applicable for removing regions from a group.
2014-12-10 16:08:52 +01:00
Thijs Wiefferink b679c49405 Update the French language file to the latest version
Adds a little more documentationto all language files, just a minor
note. Now '/as reload' will also load the a new language correctly if
you changed that in the config or language files.
2014-12-10 14:57:34 +01:00
Thijs Wiefferink dd0930bcea Removes excess debug statemements added in previous commit 2014-12-10 13:15:38 +01:00
Thijs Wiefferink 5b961564e1 Fix a bug with settings in groups.yml and region files
Now if a value has been set for a certain setting it will use it for
sure, now if you use getDoubleSetting() the following happends: 15.0 ->
15.0, 7 -> 7.0, '8.0' -> 8.0, 'bs' -> 0.0. While before only 15.0 would
see it as double, and for the others it would continue searching at the
next place (individual files > groups > default.yml).
2014-12-10 13:14:30 +01:00
Thijs Wiefferink c12314fa98 Fixes a bug with setting the owner flag
Now correctly splits the content of the owner flag at ', ' instead of
just a space (members flag already does this).
2014-12-08 18:07:04 +01:00
Thijs Wiefferink e23ad74744 Stops the unnecessary saving of the groups file.
It would mark the groups file as changed every time the groups get
loaded from the file. That would cause a unnecessary save after '/as
reload' and after restart/reload of the server.
2014-12-07 00:04:46 +01:00
Thijs Wiefferink 9957e02e65 Fix a bug with detection of files to convert
Previously it would keep sending 2 messages to console at startup saying
that is is converting files to a new format.
2014-12-06 21:43:07 +01:00
Thijs Wiefferink 07ea919aba Updates the language files to the latest version from Transifex 2014-12-05 16:20:00 +01:00
Thijs Wiefferink 2c1771cc52 Added 'friend regions' to the '/as me' command
And added teleporting to regions you are added as friend (permissions
areashop.teleportfriend and areashop.teleportfriendsign)
2014-12-05 13:48:41 +01:00
Thijs Wiefferink 83778ff803 Changes owners/members handling to WorldGuard to UUID's
Now adding uuid's to the owners/members flag in the flagProfiles section
is default, adding names is possible with 'n:<name>', groups is still
'g:<group>'. Now warnings will be displayed in the console if the size
of a schematic does not match the region size.
2014-12-04 22:56:18 +01:00
Thijs Wiefferink 0c79525144 Prevent actions on regions when it is already deleted from AreaShop
When a region is deleted with '/as del' it wil set a flag in
GeneralRegion to indicate it is deleted (isDeleted() can get it). If
this flag is set then no sign updates, saves to disk etc are being
processed by the tasks anymore. This prevents the following case: #1
task starts saving regions (makes copy of region list). #2 User 
executes '/as del' for a region, removes region file. #3 Task arrives at
the region the user just deleted and saves it to disk again #4 The
region will get loaded again next time the server starts.
2014-12-04 11:50:40 +01:00
Thijs Wiefferink e719930364 Reworks '/as info region' command for buy regions and fixes a bug
'/as info region' for buy regions now also supports more info, like the
same way as it does for rent regions. Fixed a bug with signs, now they
will correctly keep their orientation when placed again after removal
(by for example schematics).
2014-12-03 23:43:24 +01:00
Thijs Wiefferink 5568ee240b Changes the '/as info' command for rent regions to show more info
Some lines will not show up when based on config options (extending, in
advance renting, restoring), some don't show up if empty (friends,
signs) and some don't show up based on permissions (groups, teleport
location, restoring). Also adds a couple of tags to be used in language
files and the config.
2014-12-03 00:38:55 +01:00
Thijs Wiefferink 46abc8f83d Save WorldGuard regions periodically instead of directly
Now uses the saveChanges() method on RegionManager of WorldGuard, that
will only save regions that are actually changed.
2014-12-01 21:26:06 +01:00
Thijs Wiefferink cf3139f373 Changes handling WorldGuard flags, it now actually adds friends
Reworked applying flag settings configured in AreaShop to the WorldGuard
region. Now supports adding the friends to the regions, adding groups to
a region (g:groupname, would allow someone 'unlocking' functionality of
a region for a whole group of players) and adding group restrictions to
other flags (for example: 'entry: deny g:non_owners').
2014-12-01 21:00:27 +01:00
Thijs Wiefferink 59627e1b97 Add the '/as delfriend' command and minor changes the addfriend command 2014-11-29 17:08:54 +01:00
Thijs Wiefferink a25b5a5752 Fix the inactive players options, add the '/as addfriend' command
The unrent/selling of regions for inactive players now correctly checks
the option for rent regions when it is about a rent region, rent regions
also correctly check for OP now.
2014-11-29 16:37:24 +01:00
Thijs Wiefferink aceb6945fd Cleanup for code of commands, preparations for adding friends to regions
Code to dectect regions when a name of a region is not specified as
argument for commands has been cleaned and made the same for all
commands (language file cleanup is still necessary). Some functions to
manage friends for regions have been added to GeneralRegion (commands
and applying friends to regions still has to be done)
2014-11-27 23:59:44 +01:00
Thijs Wiefferink cbeffe9316 Add the stopresell command, fix a bug with reselling
If you put your region into resell mode and then sold it to the server
with /as sell, the next player buying the region would get an error or
his region would be in reselling mode directly. Now this is fixed
2014-11-27 20:38:48 +01:00
Thijs Wiefferink 9ea97fdb5d Cleans old code for replacing %clicker% tag 2014-11-25 16:48:11 +01:00
Thijs Wiefferink ed1f73fdd7 Fixes a problem with the %clicker% tag for use with sign commands
With the previous implementation it would only get replaced for commands
executed as the player, but executing as player is not wanted because
then the player should have permission for that (example: /tellraw). Now
it will properly get replaced for console and player commands attached
to a state of the sign.
2014-11-25 16:47:10 +01:00
Thijs Wiefferink 09af826f88 Add the '/as resell' command to let players sell their region to others
After executing the command the player is still owner and can do
everything like normal. The sign changes to the 'resell' section of the
chosen sign profile. The region flags change to the 'resale' section of
the flag profile (other greeting). When a player buys the region it
transfers the money to the previous owner. New schematic event and
commandevents are available for this action. Previous owner will get a
message if he is online.
A command to stop reselling your region is on the TODO list.
2014-11-24 19:16:55 +01:00
Thijs Wiefferink 1fd24d864d Adds a tag for the player name that clicks the sign
Can be used in the commands that get executed when someone clicks an
AreaShop sign. Tag is %clicker%
2014-11-24 12:58:31 +01:00
Thijs Wiefferink 4125364a96 Add highly configurable rent expire warnings for online players and some
minor changes

Rent expire warnings have profiles in config.yml, the profile can be set
in default.yml. Warning can contain a message to the player if he is
online and also have the possibility to execute certain commands.
Renamed the '/as rentduration' command to '/as setduration'.
2014-11-16 22:41:41 +01:00
Thijs Wiefferink a6f5a2eb5e Expire warning on login for players that rent regions + bugfixes
An option has been added to show a warning to players when their rent
almost runs out on login (so when they login they get a message for each
region that almost runs out, that means lower timeleft than the
'warningOnLoginTime' setting). Also a bug with schematic restoring has
been fixed and some other minor changes done.
2014-11-15 21:57:26 +01:00
Thijs Wiefferink 5eae75fef1 Add current language files again
(They got lost when changing the project setup)
2014-11-14 20:13:47 +01:00
Thijs Wiefferink 7982531e63 Merge branch 'master' of https://github.com/NLthijs48/AreaShop 2014-11-13 23:39:20 +01:00
Thijs Wiefferink 6ce15b27b7 Change the directory layout 2014-11-13 23:38:31 +01:00
Thijs Wiefferink b1809fb265 Update README.md 2014-11-13 23:17:45 +01:00
Thijs Wiefferink 0344391588 Add all changes from after the v2.0.2 release
Committing all changes made since the v2.0.2 release for now, starting
now committing will happen regularly instead of only when a version of
AreaShop is released to the public. This commit includes a large amount
of things that changed, the changelog for the upcoming version will list
them all.
2014-11-13 23:06:00 +01:00
Thijs Wiefferink 8d254e17bb Merge pull request #6 from NLthijs48/AreaShop_V1.4
Adds code of V2.0.2
2014-09-24 21:41:20 +02:00
Thijs Wiefferink 2098b9f4e3 Adds code of V2.0.2 2014-09-24 21:40:23 +02:00
Thijs Wiefferink 95e3a4a120 Update README.md 2014-09-08 12:07:00 +02:00
Thijs Wiefferink 9269279d44 Update README.md 2014-09-08 12:06:49 +02:00
Thijs Wiefferink d8fbeaf53a Merge pull request #5 from NLthijs48/AreaShop_V1.4
Adds the code from version 2.0.1
2014-09-06 22:50:51 +02:00
Thijs Wiefferink 05df539189 Merge pull request #4 from NLthijs48/AreaShop_V2.0
AreaShop v2.0.0
2014-08-28 12:13:58 +02:00
Thijs Wiefferink f20c573b06 Delete RentRegion.class 2014-08-28 11:50:13 +02:00
Thijs Wiefferink 793e3dfd1b Delete RentRegion$RentEvent.class 2014-08-28 11:50:09 +02:00
Thijs Wiefferink d7eff6c0df Delete GeneralRegion.class 2014-08-28 11:50:05 +02:00
Thijs Wiefferink 911115213f Delete BuyRegion.class 2014-08-28 11:50:02 +02:00
Thijs Wiefferink beeef8c757 Delete BuyRegion$BuyEvent.class 2014-08-28 11:49:59 +02:00
Thijs Wiefferink 60bdd50ab6 Delete UpdaterentsCommand.class 2014-08-28 11:49:55 +02:00
Thijs Wiefferink b5ba813410 Delete UpdatebuysCommand.class 2014-08-28 11:49:52 +02:00
Thijs Wiefferink 7de0b34b3b Delete UnrentCommand.class 2014-08-28 11:49:49 +02:00
Thijs Wiefferink b5077215ec Delete TeleportCommand.class 2014-08-28 11:49:46 +02:00
Thijs Wiefferink 98c45866a3 Delete SetteleportCommand.class 2014-08-28 11:49:43 +02:00
Thijs Wiefferink a96101519a Delete SellCommand.class 2014-08-28 11:49:39 +02:00
Thijs Wiefferink fc18819a95 Delete RentrestoreCommand.class 2014-08-28 11:49:34 +02:00
Thijs Wiefferink 6dd0750bea Delete RentpriceCommand.class 2014-08-28 11:49:30 +02:00
Thijs Wiefferink 36b73f57fd Delete RentdurationCommand.class 2014-08-28 11:49:27 +02:00
Thijs Wiefferink b111110251 Delete RentCommand.class 2014-08-28 11:49:24 +02:00
Thijs Wiefferink 555f648dfe Delete ReloadCommand.class 2014-08-28 11:49:21 +02:00
Thijs Wiefferink 4ac4c9ae35 Delete InfoCommand.class 2014-08-28 11:49:18 +02:00
Thijs Wiefferink 97fe92588c Delete HelpCommand.class 2014-08-28 11:49:15 +02:00
Thijs Wiefferink 8fc03b21f0 Delete CommandAreaShop.class 2014-08-28 11:49:11 +02:00
Thijs Wiefferink a74643d724 Delete BuyrestoreCommand.class 2014-08-28 11:49:08 +02:00
Thijs Wiefferink c309cbbbae Delete BuypriceCommand.class 2014-08-28 11:48:57 +02:00
Thijs Wiefferink 73ceee6f27 Delete BuyCommand.class 2014-08-28 11:48:54 +02:00
Thijs Wiefferink 9c57f434db Delete Metrics$Graph.class 2014-08-28 11:48:50 +02:00
Thijs Wiefferink f41e614d38 Delete SignChangeListener.class 2014-08-28 11:48:46 +02:00
Thijs Wiefferink 4fa1267971 Delete SignBreakListener.class 2014-08-28 11:48:43 +02:00
Thijs Wiefferink e99ca02bcb Delete Metrics$Plotter.class 2014-08-28 11:48:40 +02:00
Thijs Wiefferink 3479bcd0d8 Delete RightClickListener.class 2014-08-28 11:48:37 +02:00
Thijs Wiefferink c0cd528f0e Delete RentCheck.class 2014-08-28 11:48:32 +02:00
Thijs Wiefferink 14f379f7c6 Delete Metrics.class 2014-08-28 11:48:29 +02:00
Thijs Wiefferink 73c1f88d8c Delete CommandManager.class 2014-08-28 11:48:26 +02:00
Thijs Wiefferink 1bbca09fc6 Delete FileManager.class 2014-08-28 11:48:22 +02:00
Thijs Wiefferink 8219269fbb Delete Metrics$1.class 2014-08-28 11:48:19 +02:00
Thijs Wiefferink bf283d52b6 Delete LanguageManager.class 2014-08-28 11:48:16 +02:00
Thijs Wiefferink def6005b92 Delete AreaShop.class 2014-08-28 11:48:13 +02:00
Thijs Wiefferink 62934ceab6 Delete AreaShop$RegionType.class 2014-08-28 11:48:10 +02:00
Thijs Wiefferink 9124de9bb0 Delete AreaShop$RegionEventType.class 2014-08-28 11:48:06 +02:00
Thijs Wiefferink d5da1bb012 Delete .gitignore 2014-08-28 11:47:58 +02:00
Thijs Wiefferink 99d4cdb685 Delete .gitignore 2014-08-28 11:47:43 +02:00
Thijs Wiefferink 24ee8df215 Update README.md 2014-08-26 16:29:09 +02:00
NLthijs48 c1ef15193c Delete .gitignore 2014-05-31 00:00:51 +02:00
NLthijs48 c1e89ef75e Delete .gitignore 2014-05-31 00:00:33 +02:00
NLthijs48 56a35d373b Merge pull request #3 from NLthijs48/AreaShop-V1.1
Updates to version 1.3.0
2014-05-31 00:00:11 +02:00
NLthijs48 6a4b8f9d9a Update README.md 2014-05-16 19:52:49 +02:00
NLthijs48 ef4b599897 Delete SignChangeListener.class 2014-04-14 21:36:55 +02:00
NLthijs48 a04b96d452 Delete SignBreakListener.class 2014-04-14 21:36:52 +02:00
NLthijs48 0728ce672d Delete RightClickListener.class 2014-04-14 21:36:48 +02:00
NLthijs48 c42e1ccbe5 Delete RentCheck.class 2014-04-14 21:36:45 +02:00
NLthijs48 dfcd896cab Delete LanguageManager.class 2014-04-14 21:36:42 +02:00
NLthijs48 69ee2d5c7f Delete AreaShop.class 2014-04-14 21:36:30 +02:00
NLthijs48 b42bb38e5f Merge pull request #2 from NLthijs48/AreaShop-V1.1
Updates code to the AreaShop V1.2 release
2014-04-14 21:35:47 +02:00
NLthijs48 bed4bbac23 Create README.md 2014-04-10 22:44:44 +02:00
NLthijs48 f13534ae33 Merge pull request #1 from NLthijs48/AreaShop-V1.1
AreaShop v1.1
2014-04-10 22:41:39 +02:00
Thijs Wiefferink 0e46f01150 Adds a flexible save/restore system to .schematic files
This release adds a very configurable saving and restoring of regions.
You can let the plugin save and restore the region from/to a .schematic
file on certain events. Commands are added to change the restoring
profile for a rent/buy and the state (true, false, general) which are
respectively enabled, disabled and 'as general config option'.
2014-04-10 22:29:52 +02:00
247 changed files with 26601 additions and 8958 deletions

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
---
name: Bug report
about: Report a problem in the plugin
title: ''
labels: 'NEW, Type: Bug'
assignees: ''
---
**Current behavior**
<!--- Tell what happens currently and/or show the stacktrace if an error occured -->
**Expected behavior**
<!--- Tell what you expected to happen instead -->
**Steps to reproduce**
<!--- Exactly show how this bug can be triggered -->
1.
2.
3.
4.
**Your environment**
<!--- Indicate which versions you use -->
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
* Server platform (Bukkit, Spigot, etc.):
* Server version:
* AreaShop version:
* WorldEdit version:
* WorldGuard version:
* Vault version:
**Your config files**
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
+15
View File
@@ -0,0 +1,15 @@
---
name: Feature request
about: Suggest an idea
title: ''
labels: 'NEW, Type: Feature'
assignees: ''
---
**Describe the problem you are trying to solve with this feature request**
<!-- When I know the problem you are trying to solve I can help you to think about the best solution -->
**Describe the solution you'd like**
<!-- Describe the config settings, commands and other features that should be added -->
@@ -0,0 +1,31 @@
---
name: Support question
about: Ask help with the setup or usage of the plugin
title: ''
labels: 'NEW, Type: Support'
assignees: ''
---
**Current behavior**
<!--- Tell what happens currently -->
**Desired behavior**
<!--- Tell what you want to happen instead -->
**Your environment**
<!--- Indicate which versions you use -->
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
* Server platform (Bukkit, Spigot, etc.):
* Server version:
* AreaShop version:
* WorldEdit version:
* WorldGuard version:
* Vault version:
**Your config files**
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
+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
+194
View File
@@ -0,0 +1,194 @@
# 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+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
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
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
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### 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
.idea/*
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
.idea/sonarlint
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### Gradle ###
.gradle
build/
build-cache/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
### Gradle Patch ###
**/build/
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
-2
View File
@@ -1,2 +0,0 @@
/.project
/.classpath
-1
View File
@@ -1 +0,0 @@
/org.eclipse.jdt.core.prefs
+95
View File
@@ -0,0 +1,95 @@
plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
}
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(libs.findbugs)
implementation("io.papermc:paperlib:1.0.7")
implementation("com.github.NLthijs48:InteractiveMessenger:e7749258ca")
implementation("com.github.NLthijs48:BukkitDo:819d51ec2b")
implementation("io.github.baked-libs:dough-data:1.0.3")
implementation("com.google.inject:guice:5.1.0") {
exclude("com.google.guava", "guava")
}
implementation("com.google.inject.extensions:guice-assistedinject:5.1.0") {
exclude("com.google.guava", "guava")
}
// Project submodules
implementation(projects.areashopInterface)
implementation(projects.areashopBukkit113)
implementation(projects.areashopNms)
// Adapters
runtimeOnly(projects.adapters.plugins.worldedit)
runtimeOnly(projects.adapters.plugins.worldguard)
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
runtimeOnly(project(":adapters:platform:bukkit-1-17", "reobf"))
runtimeOnly(project(":adapters:platform:bukkit-1-18", "reobf"))
runtimeOnly(project(":adapters:platform:bukkit-1-19", "reobf"))
}
repositories {
mavenCentral()
}
tasks {
processResources {
filesMatching("plugin.yml") {
expand("version" to project.version)
}
}
assemble {
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("org.aopalliance", "${base}.aopalliance")
relocate("javax.annotation", "${base}.javax.annotation")
relocate("javax.inject", "${base}.javax.inject")
}
}
-193
View File
@@ -1,193 +0,0 @@
##############################################
# config.yml of the AreaShop plugin #
# This plugin has been created by NLThijs48 #
# Check the server minecraft.go-craft.com #
# and then the Survival server for a demo #
##############################################
########## GENERAL ##########
## Chatprefix used for all messages in the chat
chatPrefix: '&2[AreaShop]&r '
## The characters used for the prices of regions, will appear before the number, for the euro character use '%euro%'
moneyCharacter: '$'
## The characters used after a currency number, '%euro%' will become the euro character
moneyCharacterAfter: ''
## Enables / disables debug messages in the console, no need to change
debug: false
## The .yml language file that should be used, provided by this plugin: EN, NL
language: EN
## Enable Schematic saving and restoring in general
enableSchematics: true
## Maximum number of blocks to save to or restore from a .schemetic
maximumBlocks: 1000000
## Maximum number of locations the teleport function should check to find a safe spot
maximumTries: 50000
## Enable sending stats to http://mcstats.org/ (Metrics plugin)
sendStats: true
## Use colors when sending messages to console and log files
useColorsInConsole: false
## Post error messages in the console when a command run from the config fails (from the 'runCommands' section for example)
postCommandErrors: true
## Version of the config, do not change!
version: 2.0.0
## The different tags you can write on the sign to trigger the plugin
signTags:
## Tag for adding a rent region
rent: '[rent]'
## Tag for adding a buy region
buy: '[buy]'
## Tag for adding a sign to an existing region
add: '[as]'
## Configure the max total regions, max rent regions and max buy regions with different groups (-1 is unlimited)
## Assign a group to players by giving them the permission 'areashop.limits.<group>'
## Every player already has the group 'default' and ops have the unlimited group
## If a player has multiple groups the highest numbers are used
limitGroups:
default:
total: 1
rents: 1
buys: 1
unlimited:
total: -1
rents: -1
buys: -1
## Below are profiles for the signs, you can assign profiles to regions
## by setting 'general.signProfile' in default.yml, groups or individual regions
signProfiles:
default:
## Below is the format for each sign state, the following tags can be used for signs and commands:
## %region%, %player%, %uuid%, %price%, %duration%, %world%, %type%, %until%, %untilshort%
## The following sections can be added for performing certain commands when the sign is clicked:
## rightClickPlayer, rightClickConsole, shiftRightClickPlayer, shiftRightClickConsole,
## leftClickPlayer, leftClickConsole, shiftLeftClickPlayer, shiftLeftClickConsole
## Sections with 'Player' at the end will be run by the clicking player and 'Console' ones from the console
forrent:
line1: '&2&l[For Rent]'
line2: '%region%'
line3: '%duration%'
line4: '%price%'
rightClickPlayer:
- 'as rent %region%'
leftClickPlayer:
- 'as info region %region%'
rented:
line1: '&4&l[Rented]'
line2: '%region%'
line3: '%player%'
line4: '%untilshort%'
rightClickPlayer:
- 'as rent %region%'
leftClickPlayer:
- 'as info region %region%'
shiftRightClickPlayer:
- 'as unrent %region%'
forsale:
line1: '&2&l[For Sale]'
line2: '%region%'
line3: '%price%'
line4:
rightClickPlayer:
- 'as buy %region%'
leftClickPlayer:
- 'as info region %region%'
sold:
line1: '&4&l[Sold]'
line2: '%region%'
line3: '%player%'
line4:
rightClickPlayer:
- 'as buy %region%'
leftClickPlayer:
- 'as info region %region%'
shiftRightClickPlayer:
- 'as sell %region%'
## Option to run certain commands when one of these events happen
## Commands at a 'before' section will execute before the region details are changed in the AreaShop system
## and before any other actions occurred (changing signs, saving/loading schematics, etc.),
## the 'after' commands will be run when all changes are done.
## After 'before' or 'after' you can create a list of commands (see example at the created event)
eventCommandProfiles:
default:
created:
before:
after:
## - "say An AreaShop region has been created: %region%"
deleted:
before:
after:
rented:
before:
after:
extended:
before:
after:
unrented:
before:
after:
bought:
before:
after:
sold:
before:
after:
## For the following events you can specify if you want to restore or save the region to a schematic
## After 'save:' or 'restore:' you enter the name of the file, %region% will be replaced by the region name (.schematic will be added automatically)
## %type% represents the type of the region, could be 'rent' or 'buy'
## If your regions are all the same size you could use just 1 file as the restore file, just enter a name without %region%
## Be carefull with these options, it could crash your server or destroy (parts of) your world if used wrong!
schematicProfiles:
default:
created:
save: '%type%-%region%'
restore: ''
deleted:
save: ''
restore: '%type%-%region%'
rented:
save: ''
restore: ''
unrented:
save: ''
restore: '%type%-%region%'
bought:
save: ''
restore: ''
sold:
save: ''
restore: '%type%-%region%'
## Flag profiles to specify what flags should be set on the WorldGuard regions
## All region flags can be used + members, owners, priority and parent.
flagProfiles:
default:
forrent:
members: -%player%
greeting: '&2[AreaShop]&f %region% can be rented for %price% per %duration%'
rented:
members: +%player%
greeting: '&2[AreaShop]&f %region% is rented by %player% until %until%'
forsale:
members: -%player%
greeting: '&2[AreaShop]&f %region% can be bought for %price%'
sold:
members: +%player%
greeting: '&2[AreaShop]&f %region% is bought by %player%'
########## RENTING ##########
## How much seconds between checking if renting has expired (don't put this to low)
checkDelay: 60
## Timeformat to use on the signs, default is like '30-06 14:52', US format: 'MM-dd KK:mm a'
## Search for 'java SimpleDateFormat' for more options and documentation
timeFormatSign: 'dd-MM HH:mm'
## Timeformat used in the chat, default is like '30 june 2014 14:52', US format: 'MMMMMMMMMMMMMMMMM dd yyyy KK:mm a'
## Search for 'java SimpleDateFormat' for more options and documentation
timeFormatChat: 'dd MMMMMMMMMMMMMMMMM yyyy HH:mm'
## Time indicators, used for specifing rent duration on the signs
## Be careful with deleting words, will break signs using those, adding is no problem
minutes: [m, min, mins, minute, minutes, minuten, minuut]
hours: [h, hour, hours, uur, uren]
days: [d, day, days, dag, dagen]
months: [M, month, months, maanden, maand]
years: [y, year, years, jaar, jaren]
-40
View File
@@ -1,40 +0,0 @@
### All settings below are default settings and can be overridden
### by group settings or region settings (copy a section to a region or group and change them there)
########## GENERAL ##########
general:
## Set this to true to enable saving/restoring for regions as specified in the profile below, which is specified in the config
enableRestore: false
## The schematic profile as specified in the config
schematicProfile: 'default'
## The event commands profile as specified in the config
eventCommandProfile: 'default'
## The profile for the format of the sign as specified in the config
signProfile: 'default'
## The profile for the WorldGuard flags as specified in the config
flagProfile: 'default'
## The y location within the region to start searching for safe teleport spots (x and z will be in the middle of the region)
## Possible values: bottom, middle, top
teleportLocationY: bottom
## If true the teleportation algorithm only allows telportation to inside the region, otherwise it will expand algorithm
## a cube from the starting point to check for safe spots (then it could end outside the region)
## If you set a teleport location outside of the region with /as settp then setting this to true breaks that teleport (players cannot use it)
teleportIntoRegion: true
########## RENTING ##########
rent:
## The default price of a renting region
price: 1000
## The default duration of a renting region
duration: '1 day'
## The percentage of the renting price you get back if you unrent the region (price of time left will be multiplied by this/100)
moneyBack: 100
## Maximum number of extends a player can do (-1 for infinite, 0 for no extending)
maxExtends: -1
########## BUYING ##########
buy:
## The default price of a buying region
price: 1000
## The percentage of the buying price you get back if you sell the region
moneyBack: 100
-274
View File
@@ -1,274 +0,0 @@
###################################################
# English language file for the AreaShop plugin #
###################################################
# Copy this file and change the strings to your #
# favor. Then change the 'language' setting in #
# the config to the filename (excluding .yml) #
###################################################
########## General strings
total-maximum: "You can't rent and buy more than %0% region(s) in total"
cmd-notValid: "That command is not valid, use '/as help' for info"
cmd-onlyByPlayer: "This command can only be run by a player"
cmd-weOnlyByPlayer: "Using a WorldEdit selection is only possible as a player, specify the region name as extra argument"
cmd-noSelection: "You don't have a WorldEdit selection"
cmd-noRegionsFound: "No regions registered in AreaShop are found in your selection"
cmd-noWERegionsFound: "No WorldEdit regions intersecting your selection are found"
########## Help command strings
help-header: "Help page, commands that you can execute"
help-alias: "Command aliases: /areashop, /as"
help-help: "&6/as help &7-&r Shows this help page"
help-info: "&6/as info &7-&r Get info about current regions"
help-rent: "&6/as rent &7-&r Rent a region or extend your current rent"
help-buy: "&6/as buy &7-&r Buy a region"
help-unrent: "&6/as unrent &7-&r Unrent a region"
help-unrentOwn: "&6/as unrent &7-&r Unrent your own region"
help-sell: "&6/as sell &7-&r Sell a region"
help-sellOwn: "&6/as sell &7-&r Sell your own region"
help-updaterents: "&6/as updaterents &7-&r Update all rent signs and regions"
help-updatebuys: "&6/as updatebuys &7-&r Update all buy signs and regions"
help-reload: "&6/as reload &7-&r Reload the config and languages"
help-setrestore: "&6/as setrestore &7-&r Set the profile for restoring and on/off "
help-setprice: "&6/as setprice &7-&r Change the price of a rent region"
help-rentduration: "&6/as rentduration &7-&r Change the duration of a rent region"
help-teleport: "&6/as tp &7-&r Teleport to your bought/rented regions"
help-teleportAll: "&6/as tp &7-&r Teleport to a rent/buy region"
help-setteleport: "&6/as settp &7-&r Set teleport position for bought/rented regions"
help-setteleportAll: "&6/as settp &7-&r Set teleport position for a region"
help-find: "&6/as find &7-&r Find an empty buy or rent"
help-groupadd: "&6/as groupadd &7-&r Add a region to a group"
help-groupdel: "&6/as groupdel &7-&r Delete a region from a group"
help-grouplist: "&6/as grouplist &7-&r Display all groups currently registered"
help-groupinfo: "&6/as groupinfo &7-&r Display information about a group"
help-schemevent: "&6/as schemevent &7-&r Trigger a schematic event for a region"
help-add: "&6/as add &7-&r Register a region as rent or buy"
help-del: "&6/as del &7-&r Delete a registered region from AreaShop"
help-addsign: "&6/as addsign &7-&r Add a sign to an existing region"
help-delsign: "&6/as delsign &7-&r Delete the sign you are looking at"
############ Other command strings
rent-help: "/as rent [regionname], the region you stand in will be used if not specified"
rent-noPermission: "You don't have permission to rent a region"
rent-maximum: "You can't rent more than %0% region(s)"
rent-payError: "Something went wrong with paying, try again later"
rent-rented: "You rented %0% until %1%"
rent-extended: "You extended your rent of %0% until %1%"
rent-extend: "You can extend your rent by rightclicking the sign again or using /as rent"
rent-lowMoneyExtend: "You don't have enough money to extend the rent (you have %0% and you need %1%)"
rent-lowMoneyRent: "You don't have enough money to rent this region (you have %0% and you need %1%)"
rent-someoneElse: "Someone else already rented this region"
rent-notRentable: "That region is not available for renting"
rent-maxExtends: "You cannot extend this rent anymore (the maximum is %0% times), however after the rent is over you can rent this region again"
buy-help: "/as buy [regionname], the region you stand in will be used if not specified"
buy-noPermission: "You don't have permission to buy a region"
buy-notBuyable: "That region is not available for buying"
buy-maximum: "You can't buy more than %0% region(s)"
buy-payError: "Something went wrong with paying, try again later"
buy-succes: "You succesfully bought %0%"
buy-lowMoney: "You don't have enough money to buy this region (you have %0% and you need %1%)"
buy-yours: "You already own this region"
buy-someoneElse: "Someone else already bought this region"
unrent-help: "/as unrent [regionname], the region you stand in will be used if not specified"
unrent-noPermission: "You don't have permission to unrent a region"
unrent-noPermissionOther: "You don't have permission to unrent another region"
unrent-notRegistered: "The region can't be unrent because it is not registered for renting"
unrent-notRented: "The region can't be unrent because it is not rented"
unrent-unrented: "Your region has been unrented"
unrent-other: "The region has been unrented for player %0%"
unrent-expired: "Your rent of %0% has expired"
sell-help: "/as sell [regionname], the region you stand in will be used if not specified"
sell-notRegistered: "The region can't be selled because it is not registered for buying"
sell-notBought: "The region can't be selled because it is not someone's property"
sell-sold: "The region has been sold for player %0%"
sell-soldYours: "Your region has been sold"
sell-noPermission: "You don't have permission to sell a region"
sell-noPermissionOther: "You don't have permission to sell another region"
rents-updated: "All signs and regions for renting have been updated"
rents-notUpdated: "Not all signs have been updated, maybe reload fixes it"
rents-noPermission: "You don't have permission to update all rent signs and regions"
buys-updated: "All signs and regions for selling have been updated"
buys-notUpdated: "Not all signs have been updated, maybe reload fixes it"
buys-noPermission: "You don't have permission to update all buy signs and regions"
reload-reloaded: "The config has been reloaded successfully"
reload-noPermission: "You don't have permission to reload the config"
info-help: "/as info <all|rented|forrent|sold|forsale|player|region>"
info-all-rents: "Regions registered for renting: &7%0%"
info-all-noRents: "There are no regions registered for renting"
info-all-buys: "Regions registered for buying: &7%0%"
info-all-noBuys: "There are no regions registered for buying"
info-rented: "Rented regions: &7%0%"
info-noRented: "No regions are rented"
info-unrented: "Unrented regions: &7%0%"
info-noUnrented: "All regions are rented"
info-sold: "Sold regions: &7%0%"
info-noSold: "No regions are sold"
info-forsale: "Regions for sale: &7%0%"
info-noForsale: "All regions are sold"
info-playerHelp: "/as info player <name>"
info-playerRents: "Regions rented by %0%: &7%1%"
info-playerNoRents: "%0% has not rented a region"
info-playerBuys: "Regions bought by %0%: &7%1%"
info-playerNoBuys: "%0% has not bought a region"
info-regionHelp: "/as info region [name], the region you stand in will be used if not specified"
info-regionNoRenting: "%0% is not registered for renting"
info-regionRenting: "&6Renting details for %0%:"
info-regionRentedBy: "Rented by: &7%0% until %1%"
info-regionNotRented: "Currently not rented"
info-regionBuying: "&6Buying details for %0%:"
info-regionNoBuying: "%0% is not registered for buying"
info-regionNotBought: "Currently not sold"
info-regionBoughtBy: "Bought by: &7%0%"
info-regionSign: "Sign location(s): %0%"
info-regionSignLocation: "&7(%0%, %1%, %2%, %3%)&r"
info-regionNoSign: "There is no sign registered for this region"
info-regionPriceDuration: "Price: &7%0% for each %1%"
info-regionPrice: "Price: &7%0%"
info-regionRestore: "Restoring enabled: &7%0%"
info-regionRestoreProfile: "Restoring profile: &7%0%"
info-regionTPLocation: "Teleport location: &7World=%0%, X=%1%, Y=%2%, Z=%3%, Pitch=%4%, Yaw=%5%"
info-regionNoTP: "No teleport location set"
info-regionNotExisting: "Region %0% is not registered"
setrestore-help: "/as setrestore <region> <true|false|general> [profile]"
setrestore-noPermission: "You don't have permission to change the restore settings"
setrestore-notRegistered: "%0% is not registered"
setrestore-invalidSetting: "'%0%' is not a valid state, should be true, false or general"
setrestore-success: "Succesfully set the restore setting of %0% to '%1%'"
setrestore-successProfile: "Succesfully set the restore setting of %0% to '%1%' and the profile to '%2%'"
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: "%0% is not registered in AreaShop"
setprice-wrongPrice: "'%0%' is not a valid price"
setprice-successRent: "Price of region %0% changed to %1% per %2%"
setprice-successBuy: "Price of region %0% changed to %1%"
rentduration-noPermission: "You don't have permission to change the duration of a rent"
rentduration-help: "/as rentduration <amount> <identifier> [region], the region you stand in will be used if not specified"
rentduration-notRegistered: "%0% is not registered as a rent"
rentduration-wrongAmount: "'%0%' is not a valid amount, use a whole number"
rentduration-wrongFormat: "'%0%' is not a proper timeformat, check the documentation on Bukkit"
rentduration-success: "Duration of region %0% changed to '%1%'"
setup-noRegion: "You did not specify a region on the second line"
setup-wrongRegion: "The region you specified does not exist"
setup-alreadyRentSign: "The region you specified already has a sign for renting"
setup-alreadyBuySign: "The region you specified already has a sign for buying"
setup-noDuration: "You did not specify how long the region can be rented, do this on the third line"
setup-wrongDuration: "The time specified is not in the correct format, example: 1 day"
setup-noPrice: "You did not specify the price on the fourth line"
setup-wrongPrice: "You did not specify the price correctly, use a number only"
setup-rentSuccess: "Renting of region %0% is setup correctly"
setup-buySuccess: "Buying of region %0% is setup correctly"
setup-noPermissionRent: "You don't have permission for setting up renting of regions"
setup-noPermissionBuy: "You don't have permission for setting up buying of regions"
setup-couldNotDetect: "Found multiple regions with the same priority and/or parent/child relation, specify one on the second line (2 of the regions that were found: %0% and %1%)"
destroy-noPermissionRent: "You don't have permission for destroying a sign for renting a region"
destroy-noPermissionBuy: "You don't have permission for destroying a sign for buying a region"
destroy-successRent: "Renting of %0% successfully removed"
destroy-successBuy: "Buying of %0% successfully removed"
teleport-help: "/as tp <region> [sign]"
teleport-noRentOrBuy: "Region '%0%' is not registered as rent or buy"
teleport-noPermission: "You don't have permission to teleport to a region"
teleport-noPermissionOther: "You don't have permission to teleport to region you do not own"
teleport-success: "You teleported to %0%"
teleport-noSafe: "No safe position found in region %0%, no spots in region left or maximum tries exceeded (%1%/%2%)"
setteleport-help: "/as settp [region] [reset], the region you stand in will be used if not specified"
setteleport-noPermission: "You don't have permission to set the teleport location"
setteleport-noPermissionAll: "You don't have permission to set the teleport location for a region you do not own"
setteleport-noRentOrBuy: "Region '%0%' is not registered as rent or buy"
setteleport-success: "Teleport location of %0% set"
setteleport-notInside: "The location has to be inside the region"
setteleport-reset: "Teleport location of %0% has been reset"
find-help: "/as find <buy|rent> [maxprice]"
find-noPermission: "You don't have permission to teleport to signs, so you can't use find"
find-success: "Found a %0% region: %1%, while searching with a max price of your balance: %2%"
find-successMax: "Found a %0% region: %1%, while searching with a max price of %2%"
find-wrongMaxPrice: "The specified maximum price is not a correct number: %0%"
find-noneFound: "No %0% region found while searching with a max price of your balance: %1%"
find-noneFoundMax: "No %0% region found while searching with a max price of %1%"
groupadd-help: "/as groupadd <group> [region], if no region specified all regions from your WorldEdit selection are used"
groupadd-noPermission: "You don't have permission to add regions to groups"
groupadd-noRegion: "The specified region is not registered: %0%"
groupadd-success: "Region %0% has been added to group '%1%', this group now has %2% member(s)"
groupadd-failed: "Region %0% is already a member of group '%1%'"
groupadd-weSuccess: "Added to group %0%: &7%1%"
groupadd-weFailed: "Were already in group %0%: &7%1%"
groupdel-help: "/as groupdel <group> [region], if no region specified all regions from your WorldEdit selection are used"
groupdel-noPermission: "You don't have permission to remove regions from groups"
groupdel-noRegion: "The specified region is not registered: %0%"
groupdel-success: "Region %0% has been removed from group '%1%', this group now has %2% member(s)"
groupdel-failed: "Region %0% is not a member of group '%1%'"
groupdel-weSuccess: "Removed from group %0%: &7%1%"
groupdel-weFailed: "Were not in group %0% anyway: &7%1%"
grouplist-noPermission: "You don't have permission to display the registered groups"
grouplist-noGroups: "There are currently no groups registered"
grouplist-success: "The following groups are registered: &7%0%"
groupinfo-help: "/as groupinfo <group>"
groupinfo-noPermission: "You don't have permission to display information about a group"
groupinfo-noGroup: "There is no group registered with the name '%0%', use /as grouplist to check groups"
groupinfo-members: "The following regions are member of group %0%: &7%1%"
groupinfo-noMembers: "Group %0% does not have any members"
schemevent-help: "/as schemevent <region> <created|deleted|rented|unrented|bought|sold>"
schemevent-noRegion: "The specified region is not registered: %0%"
schemevent-wrongEvent: "The specified event '%0%' does not exist, use one of the following: &7%1%"
schemevent-success: "Event '%0%' has succesfully been triggered for region %1%"
schemevent-noPermission: "You don't have permission to trigger schematic events"
add-help: "/as add <rent|buy> [region] [world]"
add-noPermission: "You don't have permission to add a region to AreaShop"
add-success: "Added as %0%: &7%1%"
add-failed: "Already registered: &7%0%"
add-specifyWorld: "Specify the world of the region when using from console"
add-incorrectWorld: "World '%0%' not found, try again (case-sensitive)"
add-noRegion: "Region '%0%' does not exist in this world"
del-noRegion: "Region '%0%' is not registered in AreaShop"
del-noPermission: "You don't have permission to remove regions"
del-success: "Removed regions: &7%0%"
del-failed: "No permission to remove or not registered: &7%0%"
addsign-help: "/as addsign [region] [profile]"
addsign-noSign: "You are not looking at a sign"
addsign-noRegion: "Region '%0%' cannot be found"
addsign-noRegions: "No region found around the sign position"
addsign-couldNotDetect: "Found multiple regions around the sign, specify region as extra argument (2 of the regions that were found: %0% and %1%)"
addsign-couldNotDetectSign: "Found multiple regions around the sign, specify region on the second line (2 of the regions that were found: %0% and %1%)"
addsign-wrongProfile: "The specified profile does not exist, use one of the following (check config): &7%0%"
addsign-success: "The sign has been added to %0%"
addsign-successProfile: "The sign has been added to %0% with profile %1%"
addsign-alreadyRegistered: "That sign is already registered for region %0%"
addsign-noPermission: "You don't have permission to add a sign"
delsign-noSign: "You are not looking at a sign"
delsign-noPermission: "You don't have permission to delete a sign"
delsign-noRegion: "That sign does not belong to an AreaShop region"
delsign-success: "The sign has been removed from region %0%"
-173
View File
@@ -1,173 +0,0 @@
###################################################
# Dutch language file for the AreaShop plugin #
###################################################
# Copy this file and change the strings to your #
# favor. Then change the 'language' setting in #
# the config to the filename (excluding .yml) #
# NOT UPDATED since 1.2.1 #
###################################################
########## Command strings
total-maximum: "Je kunt niet meer dan %0% gebied(en) in totaal huren en kopen"
cmd-onlyByPlayer: "Dit commando kan alleen door een speler uitgevoert worden"
cmd-notValid: "Dat commando is niet geldig , gebruik '/as help' voor informatie"
rent-regionNotRentable: "Dat gebied is niet beschikbaar om te huren"
rent-help: "/as rent <gebiednaam>"
rent-noPermission: "Je hebt geen toestemming om een gebied te huren"
rent-maximum: "Je kunt niet meer dan %0% gebied(en) huren"
rent-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw"
rent-rented: "Je hebt %0% tot %1% gehuurd"
rent-extended: "Je hebt je huur van %0% verlengt tot %1%"
rent-extend: "Je kunt je huur verlengen door opnieuw op het bordje te klikken of gebruik te maken van /as rent"
rent-lowMoneyExtend: "Je hebt niet genoeg geld om de huur te verlengen (je hebt %0% van de %1%)"
rent-lowMoneyRent: "Je hebt niet genoeg geld om het gebied te huren (je hebt %0% van de %1%)"
rent-someoneElse: "Iemand anders heeft dit gebied al gehuurd"
rent-notRentable: "Dat gebied is niet beschikbaar om te huren"
buy-help: "/as buy <gebiednaam>"
buy-noPermission: "Je hebt geen toestemming om een gebied te kopen"
buy-notBuyable: "Dat gebied is niet beschikbaar om te kopen"
buy-maximum: "Je kunt niet meer dan %0% gebied(en) kopen"
buy-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw"
buy-succes: "Je hebt %0% succesvol gekocht"
buy-lowMoney: "Je hebt niet genoeg geld om het gebied te kopen (je hebt %0% van de %1%)"
buy-yours: "Je hebt dit gebied al gekocht"
buy-someoneElse: "Iemand anders heeft dit gebied al gekocht"
unrent-help: "/as unrent <gebiednaam>"
unrent-noPermission: "Je hebt geen toestemming om te stoppen met huren"
unrent-noPermissionOther: "Je hebt geen toestemming om iemand anders huur te stoppen"
unrent-notRegistered: "De huur kan niet gestopt worden want het gebied is niet geregistreerd om te huren"
unrent-notRented: "De huur kan niet gestopt worden want het gebied is niet gehuurd"
unrent-unrented: "De huur van je gebied is gestopt"
unrent-other: "De huur voor het gebied is gestopt voor speler %0%"
unrent-expired: "De huur van je gebied %0% is gestopt"
sell-help: "/as sell <gebiednaam>"
sell-notRegistered: "Het gebied kan niet verkocht worden want het staat niet geregistreerd om te kopen"
sell-notBought: "Het gebied kan niet verkocht worden want het is niet gekocht"
sell-sold: "Het gebied is verkocht voor speler %0%"
sell-soldYours: "Je gebied is verkocht"
sell-noPermission: "Je hebt geen toestemming om een gebied te verkopen"
sell-noPermissionOther: "Je hebt geen toestemming om een gebied van iemand anders te verkopen"
rents-updated: "Alle borden en gebieden voor de verhuur zijn geupdate"
rents-notUpdated: "Niet alle borden zijn geupdate, een reload zou het op kunnen lossen"
rents-noPermission: "Je hebt geen toestemming om alle verhuur borden en gebieden te updaten"
buys-updated: "Alle borden en gebieden voor de verkoop zijn geupdate"
buys-notUpdated: "Niet alle borden zijn geupdate, een reload zou het op kunnen lossen"
buys-noPermission: "Je hebt geen toestemming om alle verkoop borden en gebieden te updaten"
reload-reloaded: "De config is succesvol opnieuw ingeladen"
reload-noPermission: "Je hebt geen toestemming om de config opnieuw in te laden"
info-help: "/as info <all|rented|forrent|sold|forsale|player|region>"
info-all-rents: "Gebieden geregistreerd voor de verhuur: %0%"
info-all-noRents: "Er zijn geen gebieden geregistreerd voor de verhuur"
info-all-buys: "Gebieden geregistreerd voor de verkoop: %0%"
info-all-noBuys: "Er zijn geen gebieden geregistreerd voor de verkoop"
info-rented: "Verhuurde gebieden: %0%"
info-noRented: "Er zijn geen verhuurde gebieden"
info-unrented: "Gebieden te huur: %0%"
info-noUnrented: "Alle gebieden zijn verhuurd"
info-sold: "Verkochte gebieden: %0%"
info-noSold: "Alle gebieden zijn verkocht"
info-forsale: "Gebieden te koop: %0%"
info-noForsale: "Alle gebieden zijn verkocht"
info-playerHelp: "/as info player <naam>"
info-playerRents: "Gebieden gehuurd door %0%: %1%"
info-playerNoRents: "%0% heeft geen gebied gehuurd"
info-playerBuys: "Gebieden gekocht door %0%: %1%"
info-playerNoBuys: "%0% heeft geen gebieden gekocht"
info-regionHelp: "/as info region <naam>"
info-regionNoRenting: "%0% is niet geregistreerd voor verhuur"
info-regionRenting: "&6Huur informatie voor %0%"
info-regionRentedBy: "Gehuurd door: %0% tot %1%"
info-regionNotRented: "Nu niet verhuurd"
info-regionBuying: "&6Verkoop informatie voor %0%"
info-regionNoBuying: "%0% is niet geregistreerd voor verkoop"
info-regionNotBought: "Nu niet verkocht"
info-regionBoughtBy: "Gekocht door: %0%"
info-regionSign: "Plek van het bordje: wereld=%0%, X=%1%, Y=%2%, Z=%3%"
info-regionPriceDuration: "Prijs: %0% voor elke %1%"
info-regionPrice: "Prijs: %0%"
info-regionRestore: "Herstellen ingeschakeld: %0%"
info-regionRestoreProfile: "Herstel profiel: %0%"
help-header: "Help pagina, commando's die jij kunt uitvoeren"
help-alias: "Commando aliassen: /areashop, /as"
help-help: "&6/as help &7-&r Laat deze help pagina zien"
help-info: "&6/as info &7-&r Vraag informatie over gebieden op"
help-rent: "&6/as rent &7-&r Huur een gebied of verleng de huur"
help-buy: "&6/as buy &7-&r Koop een gebied"
help-unrent: "&6/as unrent &7-&r Stop de huur van een gebied"
help-unrentOwn: "&6/as unrent &7-&r Stop de huur van een eigen gebied"
help-sell: "&6/as sell &7-&r Verkoop een gebied"
help-sellOwn: "&6/as sell &7-&r Verkoop een eigen gebied"
help-updaterents: "&6/as updaterents &7-&r Update alle huur borden en gebieden"
help-updatebuys: "&6/as updatebuys &7-&r Update alle koop borden en gebieden"
help-reload: "&6/as reload &7-&r Herlaad de config en de taalbestanden"
help-rentrestore: "&6/as rentrestore &7-&r Laat dit huur gebied herstellen of niet"
help-buyrestore: "&6/as buyrestore &7-&r Laat dit koop gebied herstellen of niet"
help-rentprice: "&6/as rentprice &7-&r Verander de prijs van een huur gebied"
help-buyprice: "&6/as buyprice &7-&r Verander de prijs van een koop gebied"
help-rentduration: "&6/as rentduration &7-&r Verander de looptijd van een huur gebied"
help-teleport: "&6/as tp &7-&r Teleporteer naar je gekochte/gehuurde gebieden"
help-teleportAll: "&6/as tp &7-&r Teleporteer naar koop/huur gebieden"
rentrestore-help: "/as rentrestore <gebied> <true|false|general> [profiel]"
rentrestore-noPermission: "Je hebt geen toestemming om herstel instellingen te veranderen bij een huur gebied"
rentrestore-notRegistered: "%0% is niet geregistreerd als een huur gebied"
rentrestore-invalidSetting: "'%0%' is geen goede optie, gebruik true, false of general"
rentrestore-success: "Succesvol de herstel optie gezet van %0% naar '%1%'"
rentrestore-successProfile: "Succesvol de herstel optie gezet van %0% naar '%1%' en het profiel naar '%2%'"
buyrestore-help: "/as buyrestore <gebied> <true|false|general> [profiel]"
buyrestore-noPermission: "Je hebt geen toestemming om herstel instellingen te veranderen bij geen koop gebied"
buyrestore-notRegistered: "%0% is niet geregistreerd als een koop gebied"
buyrestore-invalidSetting: "'%0%' is geen goede optie, gebruik true, false of general"
buyrestore-success: "Succesvol de herstel optie gezet van %0% naar '%1%'"
buyrestore-successProfile: "Succesvol de herstel optie gezet van %0% naar '%1%' en het profiel naar '%2%'"
rentprice-noPermission: "Je hebt geen toestemming om de prijs van een huur gebied te veranderen"
rentprice-help: "/as rentprice <gebied> <prijs>"
rentprice-notRegistered: "%0% is niet geregistreerd als een huur gebied"
rentprice-wrongPrice: "'%0%' is geen goede prijs"
rentprice-success: "Prijs van gebied %0% is veranderd naar %1% per %2%"
buyprice-noPermission: "Je hebt geen toestemming om de prijs van een koop gebied te veranderen"
buyprice-help: "/as buyprice <gebied> <prijs>"
buyprice-notRegistered: "%0% is niet geregistreerd als koop gebied"
buyprice-wrongPrice: "'%0%' is geen goede prijs"
buyprice-success: "Prijs van gebied %0% is veranderd naar %1%"
rentduration-noPermission: "Je hebt geen toestemming om de looptijd van een huur gebied te veranderen"
rentduration-help: "/as rentduration <gebied> <aantal> <soort>"
rentduration-notRegistered: "%0% is niet geregistreerd als een huur gebied"
rentduration-wrongPrice: "'%0%' is geen goede prijs, gebruik een geheel getal"
rentduration-wrongFormat: "'%0%' is geen goed tijdformaat, bekijk de documentatie op Bukkit"
rentduration-success: "Looptijd van gebeid %0% veranderd naar '%1%'"
setup-noRegion: "Je hebt geen gebied aangegeven op de tweede regel"
setup-wrongRegion: "Het aangegeven gebied bestaat niet"
setup-alreadyRentSign: "Het aangegeven gebied heeft al een bord voor huren"
setup-alreadyBuySign: "Het aangegeven gebied heeft al een bord voor kopen"
setup-noDuration: "Je hebt geen tijdsduur voor het huren aangegeven, zet dit op de derde regel"
setup-wrongDuration: "De aangegeven tijdsduur is niet in het correcte formaat, voorbeeld: 1 dag"
setup-noPrice: "Je hebt geen prijs aangegeven op de vierde regel"
setup-wrongPrice: "Je hebt de prijs niet goed aangegeven, gebruik een nummer"
setup-rentSuccess: "Huren van gebied %0% is goed opgezet"
setup-buySuccess: "Kopen van gebied %0% is goed opgezet"
setup-noPermissionRent: "Je hebt geen toestemming om huur gebieden op te zetten"
setup-noPermissionBuy: "Je hebt geen toestemming om koop gebieden op te zetten"
setup-couldNotDetect: "Meerdere gebieden gevonden met dezelfde prioriteit en/of parent/child relatie, geeft een specifieke aan op de tweede regel (2 van de gebieden die gevonden zijn: %0% en %1%)"
teleport-help: "/as tp <gebied> <aantal> <soort>"
teleport-noRentOrBuy: "Gebied '%0%' is niet geregistreerd als koop of huur gebied"
teleport-noPermission: "Je hebt geen toestemming om te teleporteren naar een gebied"
teleport-noPermissionOther: "Je hebt geen toestemming om te teleporteren naar een gebied dat niet van jou is"
teleport-success: "Je bent naar %0% geteleporteerd"
teleport-noSafe: "Geen veilige plek gevonden in gebied %0%, verander het gebied of stel de teleporteer positie in"
-153
View File
@@ -1,153 +0,0 @@
name: AreaShop
main: nl.evolutioncoding.AreaShop.AreaShop
version: 2.0.1
depend: [Vault, WorldGuard, WorldEdit]
softdepend: [Multiverse-Core]
commands:
AreaShop:
description: For all commands use /as help
usage: /AreaShop or /AS
permission: areashop.help
permission-message: You don't have <permission>
aliases: [as]
permissions:
areashop.*:
description: Give access to all commands of AreaShop
children:
areashop.help: true
areashop.createrent: true
areashop.createbuy: true
areashop.destroyrent: true
areashop.destroybuy: true
areashop.rent: true
areashop.buy: true
areashop.unrent: true
areashop.info: true
areashop.updaterents: true
areashop.updatebuys: true
areashop.reload: true
areashop.setrestore: true
areashop.setprice: true
areashop.rentduration: true
areashop.teleportall: true
areashop.setteleportall: true
areashop.teleportsign: true
areashop.tabcomplete: true
areashop.setteleportoutsideregion: true
areashop.find: true
areashop.groupadd: true
areashop.groupdel: true
areashop.grouplist: true
areashop.groupinfo: true
areashop.limits.unlimited: true
areashop.schematicevents: true
areashop.addsign: true
areashop.delsign: true
areashop.help:
description: Allows you to see the help pages
default: true
areashop.rent:
description: Allows you to rent a region
default: true
areashop.buy:
description: Allows you to buy a region
default: true
areashop.unrent:
description: Allows you to unrent a specific region
default: op
areashop.unrentown:
description: Allows you to unrent your own region
default: true
areashop.sell:
description: Allows you to sell a specific region
default: op
areashop.sellown:
description: Allows you to sell your own region
default: true
areashop.createrent:
description: Allows you to set up signs for renting regions
default: op
areashop.createbuy:
description: Allows you to set up signs for buying regions
default: op
areashop.destroyrent:
description: Allows you to break signs used for renting regions
default: op
areashop.destroybuy:
description: Allows you to break signs used for renting regions
default: op
areashop.info:
description: Allows you check the status of regions and players
default: true
areashop.updaterents:
description: Allows you to update all rent signs and regions
default: op
areashop.updatebuys:
description: Allows you to update all buy signs and regions
default: op
areashop.reload:
description: Allows you to reload the config
default: op
areashop.setrestore:
description: Allows you to change the restore settings
default: op
areashop.setprice:
description: Allows you to change the price
default: op
areashop.rentduration:
description: Allows you to change the duration of a rent
default: op
areashop.teleport:
description: Teleport to your region
default: true
areashop.teleportall:
description: Teleport to all regions
default: true
areashop.teleportsign:
description: Teleport to signs of regions
default: true
areashop.setteleport:
description: Set the teleport spot for your region
default: true
areashop.setteleportall:
description: Set the teleport for other regions
default: op
areashop.setteleportoutsideregion:
description: Set the teleport location outside the WorldGuard region
default: op
areashop.tabcomplete:
description: Allows you to tabcomplete all commands (also where you dont have permission)
default: op
areashop.find:
description: Allows you to teleport to a free region (/as find)
default: true
areashop.groupadd:
description: Allows you to add regions to groups
default: op
areashop.groupdel:
description: Allows you to delete regions from groups
default: op
areashop.grouplist:
description: Allows you to list all the groups currently created
default: op
areashop.groupinfo:
description: Allows you to display information about a group (all members)
default: op
areashop.rentextendbypass:
description: Bypass the extend limit on rents
default: op
areashop.limits.default:
description: Assign limits as set in the 'default' group in the 'limitGroups' section of the config
default: not op
areashop.limits.unlimited:
description: Assign limits as set in the 'unlimited' group in the 'limitGroups' section of the config
default: op
areashop.schematicevents:
description: Allows you to trigger schematic events for regions
default: op
areashop.addsign:
description: Allows you to add signs to existing regions
default: op
areashop.delsign:
description: Allows you to delete signs from existing regions
default: op
@@ -0,0 +1,766 @@
package me.wiefferink.areashop;
import com.google.inject.Guice;
import com.google.inject.Injector;
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 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;
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.tools.GithubUpdateCheck;
import me.wiefferink.areashop.tools.SimpleMessageBridge;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import me.wiefferink.interactivemessenger.source.LanguageManager;
import net.milkbowl.vault.economy.Economy;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nonnull;
import java.io.File;
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;
/**
* Main class for the AreaShop plugin.
* Contains methods to get parts of the plugins functionality and definitions for constants.
*/
public final class AreaShop extends JavaPlugin implements AreaShopApi {
// Statically available instance
private static AreaShop instance = null;
// General variables
private Injector injector;
private WorldGuardPlugin worldGuard = null;
private WorldGuardInterface worldGuardInterface = null;
private WorldEditPlugin worldEdit = null;
private WorldEditInterface worldEditInterface = null;
private NMS nms;
private BukkitInterface bukkitInterface = null;
private MessageBridge messageBridge;
private IFileManager fileManager = null;
private LanguageManager languageManager = null;
private CommandManager commandManager = null;
private SignLinkerManager signLinkerManager = null;
private FeatureManager featureManager = null;
private SignManager signManager;
private SignErrorLogger signErrorLogger;
private Set<Manager> managers = null;
private boolean debug = false;
private List<String> chatprefix = null;
private boolean ready = false;
private GithubUpdateCheck githubUpdateCheck = null;
// Folders and file names
public static final String languageFolder = "lang";
public static final String schematicFolder = "schem";
public static final String regionsFolder = "regions";
public static final String groupsFile = "groups.yml";
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.log";
public static final String versionFile = "versions";
// Euro tag for in the config
public static final String currencyEuro = "%euro%";
// Constants for handling file versions
public static final String versionFiles = "files";
public static final int versionFilesCurrent = 3;
// Keys for replacing parts of flags, commands, strings
public static final String tagPlayerName = "player";
public static final String tagPlayerUUID = "uuid";
public static final String tagWorldName = "world";
public static final String tagRegionName = "region";
public static final String tagRegionType = "type";
public static final String tagPrice = "price";
public static final String tagRawPrice = "rawprice";
public static final String tagDuration = "duration";
public static final String tagRentedUntil = "until";
public static final String tagRentedUntilShort = "untilshort";
public static final String tagWidth = "width"; // x-axis
public static final String tagHeight = "height"; // y-axis
public static final String tagDepth = "depth"; // z-axis
public static final String tagVolume = "volume"; // Number of blocks in the region (accounting for polygon regions)
public static final String tagTimeLeft = "timeleft";
public static final String tagClicker = "clicker";
public static final String tagResellPrice = "resellprice";
public static final String tagRawResellPrice = "rawresellprice";
public static final String tagFriends = "friends";
public static final String tagFriendsUUID = "friendsuuid";
public static final String tagMoneyBackPercentage = "moneybackpercent";
public static final String tagMoneyBackAmount = "moneyback";
public static final String tagRawMoneyBackAmount = "rawmoneyback";
public static final String tagTimesExtended = "timesExtended";
public static final String tagMaxExtends = "maxextends";
public static final String tagExtendsLeft = "extendsleft";
public static final String tagMaxRentTime = "maxrenttime";
public static final String tagMaxInactiveTime = "inactivetime";
public static final String tagLandlord = "landlord";
public static final String tagLandlordUUID = "landlorduuid";
public static final String tagDateTime = "datetime";
public static final String tagDateTimeShort = "datetimeshort";
public static final String tagYear = "year";
public static final String tagMonth = "month";
public static final String tagDay = "day";
public static final String tagHour = "hour";
public static final String tagMinute = "minute";
public static final String tagSecond = "second";
public static final String tagMillisecond = "millisecond";
public static final String tagEpoch = "epoch";
public static final String tagTeleportX = "tpx";
public static final String tagTeleportY = "tpy";
public static final String tagTeleportZ = "tpz";
public static final String tagTeleportBlockX = "tpblockx";
public static final String tagTeleportBlockY = "tpblocky";
public static final String tagTeleportBlockZ = "tpblockz";
public static final String tagTeleportPitch = "tppitch";
public static final String tagTeleportYaw = "tpyaw";
public static final String tagTeleportPitchRound = "tppitchround";
public static final String tagTeleportYawRound = "tpyawround";
public static final String tagTeleportWorld = "tpworld";
public static AreaShop getInstance() {
return AreaShop.instance;
}
/**
* Called on start or reload of the server.
*/
@Override
public void onEnable() {
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.adapters.platform." + serverVersion + ".NMSImpl");
this.nms = nmsImpl.asSubclass(NMS.class).getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
error("Failed to initialize NMS implementation!");
shutdownOnError();
return;
}
// 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 weHandlerVersion;
Plugin plugin = getServer().getPluginManager().getPlugin("WorldEdit");
if(!(plugin instanceof WorldEditPlugin) || !plugin.isEnabled()) {
error("WorldEdit plugin is not present or has not loaded correctly");
return;
} else {
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 {
weHandlerVersion = "WorldEditHandler";
}
}
plugin = getServer().getPluginManager().getPlugin("WorldGuard");
if(!(plugin instanceof WorldGuardPlugin) || !plugin.isEnabled()) {
error("WorldGuard plugin is not present or has not loaded correctly");
shutdownOnError();
return;
} else {
this.worldGuard = (WorldGuardPlugin) plugin;
}
DependencyModule dependencyModule = new DependencyModule(this.worldEdit, this.worldGuard, getEconomy(), getPermissionProvider());
// Load WorldEdit
try {
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 " + weHandlerVersion + "), report this problem to the author: " + ExceptionUtils.getStackTrace(e));
shutdownOnError();
return;
}
// Load WorldGuard
try {
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, report this problem to the author:" + ExceptionUtils.getStackTrace(e));
shutdownOnError();
return;
}
try {
Class<?> clazz = Class.forName("me.wiefferink.areashop.handlers.BukkitHandler1_13");
bukkitInterface = (BukkitInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this);
} catch (Exception e) {
error("Could not load the Bukkit handler (used for sign updates), report this problem to the author:", ExceptionUtils.getStackTrace(e));
shutdownOnError();
return;
}
AreaShopModule asModule = new AreaShopModule(this, messageBridge, nms, bukkitInterface, worldEditInterface, worldGuardInterface, signErrorLogger, dependencyModule);
injector = Guice.createInjector(Stage.PRODUCTION, new BukkitModule(getServer()), asModule);
// Load all data from files and check versions
fileManager = injector.getInstance(IFileManager.class);
managers.add((FileManager) fileManager);
boolean loadFilesResult = fileManager.loadFiles(false);
error = error || !loadFilesResult;
setupLanguageManager();
featureManager = injector.getInstance(FeatureManager.class);
featureManager.initializeFeatures(injector);
managers.add(featureManager);
signManager = new SignManager();
managers.add(signManager);
// Register the event listeners
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge), this);
setupTasks();
// Startup the CommandManager (registers itself for the command)
commandManager = injector.getInstance(CommandManager.class);
managers.add(commandManager);
// Create a signLinkerManager
signLinkerManager = injector.getInstance(SignLinkerManager.class);
managers.add(signLinkerManager);
// Register dynamic permission (things declared in config)
registerDynamicPermissions();
// Don't initialize the updatechecker if disabled in the config
if(getConfig().getBoolean("checkForUpdates")) {
githubUpdateCheck = new GithubUpdateCheck(
this,
"md5sha256",
"AreaShop"
).withVersionComparator((latestVersion, currentVersion) ->
!cleanVersion(latestVersion).equals(cleanVersion(currentVersion))
).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/");
for(Player player : Utils.getOnlinePlayers()) {
notifyUpdate(player);
}
});
}
}
/**
* Notify a player about an update if he wants notifications about it and an update is available.
* @param sender CommandSender to notify
*/
public void notifyUpdate(CommandSender sender) {
if(githubUpdateCheck != null && githubUpdateCheck.hasUpdate() && sender.hasPermission("areashop.notifyupdate")) {
messageBridge.message(sender, "update-playerNotify", cleanVersion(githubUpdateCheck.getCurrentVersion()), cleanVersion(githubUpdateCheck.getLatestVersion()));
}
}
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
* @return Cleaned up version (removed prefixes and suffixes)
*/
private String cleanVersion(String version) {
version = version.toLowerCase();
// Strip 'v' as used on Github tags
if(version.startsWith("v")) {
version = version.substring(1);
}
// Strip build number as used by Jenkins
if(version.contains("#")) {
version = version.substring(0, version.indexOf("#"));
}
return version;
}
/**
* Called on shutdown or reload of the server.
*/
@Override
public void onDisable() {
Bukkit.getServer().getScheduler().cancelTasks(this);
// Cleanup managers
for(Manager manager : managers) {
manager.shutdown();
}
signErrorLogger.saveIfDirty();
HandlerList.unregisterAll(this);
}
/**
* Indicates if the plugin is ready to be used.
* @return true if the plugin is ready, false otherwise
*/
public boolean isReady() {
return ready;
}
/**
* Set if the plugin is ready to be used or not (not to be used from another plugin!).
* @param ready Indicate if the plugin is ready to be used
*/
public void setReady(boolean ready) {
this.ready = ready;
}
/**
* Set if the plugin should output debug messages (loaded from config normally).
* @param debug Indicates if the plugin should output debug messages or not
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
/**
* Setup a new LanguageManager.
*/
private void setupLanguageManager() {
languageManager = new LanguageManager(
this,
languageFolder,
getConfig().getString("language"),
"EN",
chatprefix
);
}
/**
* Set the chatprefix to use in the chat (loaded from config normally).
* @param chatprefix The string to use in front of chat messages (supports formatting codes)
*/
public void setChatprefix(List<String> chatprefix) {
this.chatprefix = chatprefix;
}
public NMS getNms() {
return nms;
}
public SignErrorLogger getSignErrorLogger() {
return signErrorLogger;
}
/**
* Function to get the WorldGuard plugin.
* @return WorldGuardPlugin
*/
@Override
public WorldGuardPlugin getWorldGuard() {
return worldGuard;
}
/**
* Function to get WorldGuardInterface for version dependent things.
* @return WorldGuardInterface
*/
public WorldGuardInterface getWorldGuardHandler() {
return this.worldGuardInterface;
}
@Nonnull
public SignManager getSignManager() {
return signManager;
}
/**
* Get the RegionManager.
* @param world World to get the RegionManager for
* @return RegionManager for the given world, if there is one, otherwise null
*/
public RegionManager getRegionManager(World world) {
return this.worldGuardInterface.getRegionManager(world);
}
/**
* Function to get the WorldEdit plugin.
* @return WorldEditPlugin
*/
@Override
public WorldEditPlugin getWorldEdit() {
return worldEdit;
}
/**
* Function to get WorldGuardInterface for version dependent things.
* @return WorldGuardInterface
*/
public WorldEditInterface getWorldEditHandler() {
return this.worldEditInterface;
}
/**
* Function to get the LanguageManager.
* @return the LanguageManager
*/
public LanguageManager getLanguageManager() {
return languageManager;
}
/**
* Get the BukkitHandler, for sign interactions.
* @return BukkitHandler
*/
public BukkitInterface getBukkitHandler() {
return this.bukkitInterface;
}
/**
* Function to get the CommandManager.
* @return the CommandManager
*/
@Nonnull
@Override
public CommandManager getCommandManager() {
return commandManager;
}
/**
* Get the SignLinkerManager.
* Handles sign linking mode.
* @return The SignLinkerManager
*/
@Nonnull
@Override
public SignLinkerManager getSignlinkerManager() {
return signLinkerManager;
}
/**
* Get the FeatureManager.
* Manages region specific features.
* @return The FeatureManager
*/
@Nonnull
@Override
public FeatureManager getFeatureManager() {
return featureManager;
}
/**
* Function to get the Vault plugin.
* @return Economy
*/
@Deprecated
private Economy getEconomy() {
RegisteredServiceProvider<Economy> economy = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if(economy == null) {
error("There is no economy provider to support Vault, make sure you installed an economy plugin");
return null;
}
return economy.getProvider();
}
/**
* Get the Vault permissions provider.
* @return Vault permissions provider
*/
@Deprecated
private net.milkbowl.vault.permission.Permission getPermissionProvider() {
RegisteredServiceProvider<net.milkbowl.vault.permission.Permission> permissionProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider == null) {
return null;
}
return permissionProvider.getProvider();
}
/**
* Check for a permission of a (possibly offline) player.
* @param offlinePlayer OfflinePlayer to check
* @param permission Permission to check
* @return true if the player has the permission, false if the player does not have permission or, is offline and there is not Vault-compatible permission plugin
*/
public boolean hasPermission(OfflinePlayer offlinePlayer, String permission) {
// Online, return through Bukkit
if(offlinePlayer.getPlayer() != null) {
return offlinePlayer.getPlayer().hasPermission(permission);
}
// Resolve while offline if possible
net.milkbowl.vault.permission.Permission permissionProvider = getPermissionProvider();
if(permissionProvider != null) {
// TODO: Should we provide a world here?
return permissionProvider.playerHas(null, offlinePlayer, permission);
}
// Player offline and no offline permission provider available, safely say that there is no permission
return false;
}
/**
* Method to get the FileManager (loads/save regions and can be used to get regions).
* @return The fileManager
*/
public IFileManager getFileManager() {
return fileManager;
}
/**
* Register dynamic permissions controlled by config settings.
*/
private void registerDynamicPermissions() {
// Register limit groups of amount of regions a player can have
ConfigurationSection section = getConfig().getConfigurationSection("limitGroups");
if(section == null) {
return;
}
for(String group : section.getKeys(false)) {
if(!"default".equals(group)) {
Permission perm = new Permission("areashop.limits." + group);
try {
Bukkit.getPluginManager().addPermission(perm);
} catch(IllegalArgumentException e) {
warn("Could not add the following permission to be used as limit: " + perm.getName());
}
}
}
Bukkit.getPluginManager().recalculatePermissionDefaults(Bukkit.getPluginManager().getPermission("playerwarps.limits"));
}
/**
* Register all required tasks.
*/
private void setupTasks() {
long signLogTicks = Utils.millisToTicks(TimeUnit.MINUTES.toMillis(5));
Bukkit.getScheduler().runTaskTimerAsynchronously(this,
() -> signErrorLogger.saveIfDirty(),
signLogTicks,
signLogTicks);
// Rent expiration timer
long expirationCheck = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("expiration.delay"));
final AreaShop finalPlugin = this;
if(expirationCheck > 0) {
Do.syncTimer(expirationCheck, () -> {
if(isReady()) {
finalPlugin.getFileManager().checkRents();
AreaShop.debugTask("Checking rent expirations...");
} else {
AreaShop.debugTask("Skipped checking rent expirations, plugin not ready");
}
});
}
// Inactive unrenting/selling timer
long inactiveCheck = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("inactive.delay"));
if(inactiveCheck > 0) {
Do.syncTimer(inactiveCheck, () -> {
if(isReady()) {
finalPlugin.getFileManager().checkForInactiveRegions();
AreaShop.debugTask("Checking for regions with players that are inactive too long...");
} else {
AreaShop.debugTask("Skipped checking for regions of inactive players, plugin not ready");
}
});
}
// Periodic updating of signs for timeleft tags
long periodicUpdate = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("signs.delay"));
if(periodicUpdate > 0) {
Do.syncTimer(periodicUpdate, () -> {
if(isReady()) {
finalPlugin.getFileManager().performPeriodicSignUpdate();
AreaShop.debugTask("Performing periodic sign update...");
} else {
AreaShop.debugTask("Skipped performing periodic sign update, plugin not ready");
}
});
}
// Saving regions and group settings
long saveFiles = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("saving.delay"));
if(saveFiles > 0) {
Do.syncTimer(saveFiles, () -> {
if(isReady()) {
finalPlugin.getFileManager().saveRequiredFiles();
AreaShop.debugTask("Saving required files...");
} else {
AreaShop.debugTask("Skipped saving required files, plugin not ready");
}
});
}
// Sending warnings about rent regions to online players
long expireWarning = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("expireWarning.delay"));
if(expireWarning > 0) {
Do.syncTimer(expireWarning, () -> {
if(isReady()) {
finalPlugin.getFileManager().sendRentExpireWarnings();
AreaShop.debugTask("Sending rent expire warnings...");
} else {
AreaShop.debugTask("Skipped sending rent expire warnings, plugin not ready");
}
});
}
// Update all regions on startup
if(getConfig().getBoolean("updateRegionsOnStartup")) {
Do.syncLater(20, () -> {
finalPlugin.getFileManager().updateAllRegions();
AreaShop.debugTask("Updating all regions at startup...");
});
}
}
/**
* Return the config.
*/
@Override
public YamlConfiguration getConfig() {
return fileManager.getConfig();
}
/**
* Sends an debug message to the console.
* @param message The message that should be printed to the console
*/
public static void debug(Object... message) {
if(AreaShop.getInstance().debug) {
info("Debug: " + StringUtils.join(message, " "));
}
}
/**
* Non-static debug to use as implementation of the interface.
* @param message Object parts of the message that should be logged, toString() will be used
*/
@Override
public void debugI(Object... message) {
AreaShop.debug(StringUtils.join(message, " "));
}
/**
* 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, " "));
}
/**
* Print a warning to the console.
* @param message The message to print
*/
public static void warn(Object... message) {
AreaShop.getInstance().getLogger().warning(StringUtils.join(message, " "));
}
/**
* Print an error to the console.
* @param message The message to print
*/
public static void error(Object... message) {
AreaShop.getInstance().getLogger().severe(StringUtils.join(message, " "));
}
/**
* Print debug message for periodic task.
* @param message The message to print
*/
public static void debugTask(Object... message) {
if(AreaShop.getInstance().getConfig().getBoolean("debugTask")) {
AreaShop.debug(StringUtils.join(message, " "));
}
}
/**
* Reload all files of the plugin and update all regions.
* @param confirmationReceiver The CommandSender which should be notified when complete, null for nobody
*/
public void reload(final CommandSender confirmationReceiver) {
setReady(false);
fileManager.saveRequiredFilesAtOnce();
fileManager.loadFiles(true);
setupLanguageManager();
messageBridge.message(confirmationReceiver, "reload-reloading");
fileManager.checkRents();
fileManager.updateAllRegions(confirmationReceiver);
}
/**
* Reload all files of the plugin and update all regions.
*/
public void reload() {
reload(null);
}
}
@@ -0,0 +1,39 @@
package me.wiefferink.areashop;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.managers.CommandManager;
import me.wiefferink.areashop.managers.FeatureManager;
import me.wiefferink.areashop.managers.SignLinkerManager;
import javax.annotation.Nonnull;
public interface AreaShopApi extends AreaShopInterface {
/**
* Function to get the CommandManager.
*
* @return the CommandManager
*/
@Nonnull CommandManager getCommandManager();
/**
* Get the SignLinkerManager.
* Handles sign linking mode.
*
* @return The SignLinkerManager
*/
@Nonnull SignLinkerManager getSignlinkerManager();
/**
* Get the FeatureManager.
* Manages region specific features.
*
* @return The FeatureManager
*/
@Nonnull FeatureManager getFeatureManager();
@Nonnull SignManager getSignManager();
}
@@ -0,0 +1,21 @@
package me.wiefferink.areashop;
public interface MessageBridge {
/**
* Send a message to a target without a prefix.
*
* @param target The target to send the message to
* @param key The key of the language string
* @param replacements The replacements to insert in the message
*/
void messageNoPrefix(Object target, String key, Object... replacements);
/**
* Send a message to a target, prefixed by the default chat prefix.
*
* @param target The target to send the message to
* @param key The key of the language string
* @param replacements The replacements to insert in the message
*/
void message(Object target, String key, Object... replacements);
}
@@ -0,0 +1,346 @@
package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.IFileManager;
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.Utils;
import me.wiefferink.bukkitdo.Do;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
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;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.UUID;
import java.util.stream.Collectors;
@Singleton
public class AddCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private AreaShop plugin;
@Inject
private WorldEditInterface worldEditInterface;
@Inject
private WorldGuardInterface worldGuardInterface;
@Inject
private RegionFactory regionFactory;
@Override
public String getCommandStart() {
return "areashop add";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.createrent")
|| target.hasPermission("areashop.createrent.member")
|| target.hasPermission("areashop.createrent.owner")
|| target.hasPermission("areashop.createbuy")
|| target.hasPermission("areashop.createbuy.member")
|| target.hasPermission("areashop.createbuy.owner")) {
return "help-add";
}
return null;
}
@Override
public void execute(final CommandSender sender, final String[] args) {
if(!sender.hasPermission("areashop.createrent")
&& !sender.hasPermission("areashop.createrent.member")
&& !sender.hasPermission("areashop.createrent.owner")
&& !sender.hasPermission("areashop.createbuy")
&& !sender.hasPermission("areashop.createbuy.member")
&& !sender.hasPermission("areashop.createbuy.owner")) {
messageBridge.message(sender, "add-noPermission");
return;
}
if(args.length < 2 || args[1] == null || (!"rent".equalsIgnoreCase(args[1]) && !"buy".equalsIgnoreCase(args[1]))) {
messageBridge.message(sender, "add-help");
return;
}
Map<String, ProtectedRegion> regions = new HashMap<>();
World world;
Player player = null;
if(sender instanceof Player) {
player = (Player)sender;
}
if(args.length == 2) {
if(player == null) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
return;
}
world = selection.getWorld();
regions = Utils.getWorldEditRegionsInSelection(selection).stream().collect(Collectors.toMap(ProtectedRegion::getId, region -> region));
if(regions.isEmpty()) {
messageBridge.message(player, "cmd-noWERegionsFound");
return;
}
} else {
if(player != null) {
if(args.length == 4) {
world = Bukkit.getWorld(args[3]);
if(world == null) {
messageBridge.message(sender, "add-incorrectWorld", args[3]);
return;
}
} else {
world = ((Player)sender).getWorld();
}
} else {
if(args.length < 4) {
messageBridge.message(sender, "add-specifyWorld");
return;
} else {
world = Bukkit.getWorld(args[3]);
if(world == null) {
messageBridge.message(sender, "add-incorrectWorld", args[3]);
return;
}
}
}
ProtectedRegion region = plugin.getRegionManager(world).getRegion(args[2]);
if(region == null) {
messageBridge.message(sender, "cmd-noRegion", args[2]);
return;
}
regions.put(args[2], region);
}
final boolean isRent = "rent".equalsIgnoreCase(args[1]);
final Player finalPlayer = player;
AreaShop.debug("Starting add task with " + regions.size() + " regions");
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
TreeSet<GeneralRegion> regionsAlready = new TreeSet<>();
TreeSet<GeneralRegion> regionsAlreadyOtherWorld = new TreeSet<>();
TreeSet<GeneralRegion> regionsRentCancelled = new TreeSet<>(); // Denied by an event listener
TreeSet<GeneralRegion> regionsBuyCancelled = new TreeSet<>(); // Denied by an event listener
TreeSet<String> namesBlacklisted = new TreeSet<>();
TreeSet<String> namesNoPermission = new TreeSet<>();
TreeSet<String> namesAddCancelled = new TreeSet<>(); // Denied by an event listener
Do.forAll(
plugin.getConfig().getInt("adding.regionsPerTick"),
regions.entrySet(),
regionEntry -> {
String regionName = regionEntry.getKey();
ProtectedRegion region = regionEntry.getValue();
// Determine if the player is an owner or member of the region
boolean isMember = finalPlayer != null && worldGuardInterface.containsMember(region, finalPlayer.getUniqueId());
boolean isOwner = finalPlayer != null && worldGuardInterface.containsOwner(region, finalPlayer.getUniqueId());
String type;
if(isRent) {
type = "rent";
} else {
type = "buy";
}
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 == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
regionsAlreadyOtherWorld.add(plugin.getFileManager().getRegion(regionName));
} else if(result == IFileManager.AddResult.BLACKLISTED) {
namesBlacklisted.add(regionName);
} else if(result == IFileManager.AddResult.NOPERMISSION) {
namesNoPermission.add(regionName);
} else {
// Check if the player should be landlord
boolean landlord = (!sender.hasPermission("areashop.create" + type)
&& ((sender.hasPermission("areashop.create" + type + ".owner") && isOwner)
|| (sender.hasPermission("areashop.create" + type + ".member") && isMember)));
List<UUID> existing = new ArrayList<>();
existing.addAll(worldGuardInterface.getOwners(region).asUniqueIdList());
existing.addAll(worldGuardInterface.getMembers(region).asUniqueIdList());
AreaShop.debug("regionAddLandlordStatus:", regionName,
"landlord:", landlord,
"existing:", existing,
"isMember:", isMember,
"isOwner:", isOwner,
"createPermission:", sender.hasPermission("areashop.create" + type),
"ownerPermission:", sender.hasPermission("areashop.create" + type + ".owner"),
"memberPermission:", sender.hasPermission("areashop.create" + type + ".member"));
if(isRent) {
RentRegion rent = regionFactory.createRentRegion(regionName, world);
// Set landlord
if(landlord) {
rent.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
}
AddingRegionEvent event = plugin.getFileManager().addRegion(rent);
if (event.isCancelled()) {
namesAddCancelled.add(rent.getName());
return;
}
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
rent.update();
// Add existing owners/members if any
if(!landlord && !existing.isEmpty()) {
UUID rentBy = existing.remove(0);
OfflinePlayer rentByPlayer = Bukkit.getOfflinePlayer(rentBy);
RentingRegionEvent rentingRegionEvent = new RentingRegionEvent(rent, rentByPlayer, false);
Bukkit.getPluginManager().callEvent(rentingRegionEvent);
if(rentingRegionEvent.isCancelled()) {
regionsRentCancelled.add(rent);
} else {
// Add values to the rent and send it to FileManager
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
rent.setRenter(rentBy);
rent.updateLastActiveTime();
// Fire schematic event and updated times extended
rent.handleSchematicEvent(GeneralRegion.RegionEvent.RENTED);
// Add others as friends
for(UUID friend : existing) {
rent.getFriendsFeature().addFriend(friend, null);
}
rent.notifyAndUpdate(new RentedRegionEvent(rent, false));
}
}
regionsSuccess.add(rent);
} else {
BuyRegion buy = regionFactory.createBuyRegion(regionName, world);
// Set landlord
if(landlord) {
buy.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
}
AddingRegionEvent event = plugin.getFileManager().addRegion(buy);
if (event.isCancelled()) {
namesAddCancelled.add(buy.getName());
return;
}
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
buy.update();
// Add existing owners/members if any
if(!landlord && !existing.isEmpty()) {
UUID buyBy = existing.remove(0);
OfflinePlayer buyByPlayer = Bukkit.getOfflinePlayer(buyBy);
BuyingRegionEvent buyingRegionEvent = new BuyingRegionEvent(buy, buyByPlayer);
Bukkit.getPluginManager().callEvent(buyingRegionEvent);
if(buyingRegionEvent.isCancelled()) {
regionsBuyCancelled.add(buy);
} else {
// Set the owner
buy.setBuyer(buyBy);
buy.updateLastActiveTime();
// Update everything
buy.handleSchematicEvent(GeneralRegion.RegionEvent.BOUGHT);
// Add others as friends
for (UUID friend : existing) {
buy.getFriendsFeature().addFriend(friend, null);
}
buy.notifyAndUpdate(new BoughtRegionEvent(buy));
}
}
regionsSuccess.add(buy);
}
}
},
() -> {
if(!regionsSuccess.isEmpty()) {
messageBridge.message(sender, "add-success", args[1], Utils.combinedMessage(regionsSuccess, "region"));
}
if(!regionsAlready.isEmpty()) {
messageBridge.message(sender, "add-failed", Utils.combinedMessage(regionsAlready, "region"));
}
if(!regionsAlreadyOtherWorld.isEmpty()) {
messageBridge.message(sender, "add-failedOtherWorld", Utils.combinedMessage(regionsAlreadyOtherWorld, "region"));
}
if(!regionsRentCancelled.isEmpty()) {
messageBridge.message(sender, "add-rentCancelled", Utils.combinedMessage(regionsRentCancelled, "region"));
}
if(!regionsBuyCancelled.isEmpty()) {
messageBridge.message(sender, "add-buyCancelled", Utils.combinedMessage(regionsBuyCancelled, "region"));
}
if(!namesBlacklisted.isEmpty()) {
messageBridge.message(sender, "add-blacklisted", Utils.createCommaSeparatedList(namesBlacklisted));
}
if(!namesNoPermission.isEmpty()) {
messageBridge.message(sender, "add-noPermissionRegions", Utils.createCommaSeparatedList(namesNoPermission));
messageBridge.message(sender, "add-noPermissionOwnerMember");
}
if(!namesAddCancelled.isEmpty()) {
messageBridge.message(sender, "add-rentCancelled", Utils.createCommaSeparatedList(namesAddCancelled));
}
}
);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
if(sender.hasPermission("areashop.createrent")) {
result.add("rent");
}
if(sender.hasPermission("areashop.createbuy")) {
result.add("buy");
}
} else if(toComplete == 3) {
if(sender instanceof Player) {
Player player = (Player)sender;
if(sender.hasPermission("areashop.createrent") || sender.hasPermission("areashop.createbuy")) {
for(ProtectedRegion region : plugin.getRegionManager(player.getWorld()).getRegions().values()) {
result.add(region.getId());
}
}
}
}
return result;
}
}
@@ -0,0 +1,154 @@
package me.wiefferink.areashop.commands;
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.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 IFileManager fileManager;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop addfriend";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
return "help-addFriend";
}
return null;
}
@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;
}
if(args.length < 2) {
messageBridge.message(sender, "addfriend-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.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;
}
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);
}
}
}
@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;
}
}
@@ -0,0 +1,144 @@
package me.wiefferink.areashop.commands;
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.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
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;
import java.util.Set;
@Singleton
public class AddsignCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private SignManager signManager;
@Inject
private Plugin plugin;
@Inject
private BukkitInterface bukkitInterface;
@Override
public String getCommandStart() {
return "areashop addsign";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.addsign")) {
return "help-addsign";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.addsign")) {
messageBridge.message(sender, "addsign-noPermission");
return;
}
if(!(sender instanceof 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) {
block = next;
}
}
if(block == null || !Materials.isSign(block.getType())) {
messageBridge.message(sender, "addsign-noSign");
return;
}
GeneralRegion region;
if(args.length > 1) {
// Get region by argument
region = fileManager.getRegion(args[1]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[1]);
return;
}
} else {
// Get region by sign position
List<GeneralRegion> regions = Utils.getImportantRegions(block.getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "addsign-noRegions");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
return;
}
region = regions.get(0);
}
String profile = null;
if(args.length > 2) {
profile = args[2];
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
if(!profiles.contains(profile)) {
messageBridge.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
return;
}
}
Optional<RegionSign> optionalRegionSign = signManager.signFromLocation(block.getLocation());
if(optionalRegionSign.isPresent()) {
RegionSign regionSign = optionalRegionSign.get();
messageBridge.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
return;
}
region.getSignsFeature().addSign(block.getLocation(), block.getType(), bukkitInterface.getSignFacing(block), profile);
if(profile == null) {
messageBridge.message(sender, "addsign-success", region);
} else {
messageBridge.message(sender, "addsign-successProfile", profile, region);
}
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(fileManager.getRegionNames());
} else if(toComplete == 3) {
result.addAll(plugin.getConfig().getStringList("signProfiles"));
}
return result;
}
}
@@ -0,0 +1,82 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class BuyCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private Plugin plugin;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop buy";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.buy")) {
return "help-buy";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.buy")) {
messageBridge.message(sender, "buy-noPermission");
return;
}
if(!(sender instanceof 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) {
messageBridge.message(player, "buy-notBuyable", args[1]);
} else {
region.buy(player);
}
} else {
// get the region by location
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
} else {
regions.get(0).buy(player);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(BuyRegion region : fileManager.getBuysRef()) {
if(!region.isSold()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,99 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.interactivemessenger.processing.Message;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Abstract class for generalising command classes.
*/
public abstract class CommandAreaShop {
private final Map<String, CommandTime> lastUsed;
protected CommandAreaShop() {
lastUsed = new HashMap<>();
}
/**
* Check if this Command instance can execute the given command and arguments.
* @param command The command to check for execution
* @param args The arguments to check
* @return true if it can execute the command, false otherwise
*/
public boolean canExecute(Command command, String[] args) {
String commandString = command.getName() + " " + StringUtils.join(args, " ");
if(commandString.length() > getCommandStart().length()) {
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase() + " ");
}
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase());
}
/**
* Get a list of string to complete a command with (raw list, not matching ones not filtered out).
* @param toComplete The number of the argument that has to be completed
* @param start The already given start of the command
* @param sender The CommandSender that wants to tab complete
* @return A collection with all the possibilities for argument to complete
*/
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
}
/**
* Get the argument that comes after the base command that this command reacts to.
* @return The string that should be in front of the command for this class to act
*/
public abstract String getCommandStart();
/**
* Returns the correct help string key to be used on the help page.
* @param target The CommandSender that the help message is for
* @return The help message key according to the permissions of the reciever
*/
public abstract String getHelp(CommandSender target);
/**
* Execute a (sub)command if the conditions are met.
* @param sender The commandSender that executed the command
* @param args The arguments that are given
*/
public abstract void execute(CommandSender sender, String[] args);
/**
* Confirm a command.
* @param sender To confirm it for, or send a message to confirm
* @param args Command args
* @param message Message to send when confirmation is required
* @return true if confirmed, false if confirmation is required
*/
public boolean confirm(CommandSender sender, String[] args, Message message) {
String command = "/" + getCommandStart() + " " + StringUtils.join(args, " ", 1, args.length);
long now = System.currentTimeMillis();
CommandTime last = lastUsed.get(sender.getName());
if(last != null && last.command.equalsIgnoreCase(command) && last.time > (now - 1000 * 60)) {
return true;
}
message.prefix().append(Message.fromKey("confirm-yes").replacements(command)).send(sender);
lastUsed.put(sender.getName(), new CommandTime(command, now));
return false;
}
private static class CommandTime {
public final String command;
public final long time;
CommandTime(String command, long time) {
this.command = command;
this.time = time;
}
}
}
@@ -0,0 +1,161 @@
package me.wiefferink.areashop.commands;
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.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 org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
@Singleton
public class DelCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private WorldEditInterface worldEditInterface;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop del";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.destroyrent") || target.hasPermission("areashop.destroybuy") || target.hasPermission("areashop.destroyrent.landlord") || target.hasPermission("areashop.destroybuy.landlord")) {
return "help-del";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.destroybuy")
&& !sender.hasPermission("areashop.destroybuy.landlord")
&& !sender.hasPermission("areashop.destroyrent")
&& !sender.hasPermission("areashop.destroyrent.landlord")) {
messageBridge.message(sender, "del-noPermission");
return;
}
if(args.length < 2) {
// Only players can have a selection
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
if(regions == null || regions.isEmpty()) {
messageBridge.message(player, "cmd-noRegionsFound");
return;
}
// Start removing the regions that he has permission for
ArrayList<String> namesSuccess = new ArrayList<>();
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
TreeSet<GeneralRegion> regionsCancelled = new TreeSet<>();
for(GeneralRegion region : regions) {
boolean isLandlord = region.isLandlord(((Player)sender).getUniqueId());
if(region instanceof RentRegion) {
if(!sender.hasPermission("areashop.destroyrent") && !(isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
regionsFailed.add(region);
continue;
}
} else if(region instanceof BuyRegion) {
if(!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
regionsFailed.add(region);
continue;
}
}
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
if (event.isCancelled()) {
regionsCancelled.add(region);
} else {
namesSuccess.add(region.getName());
}
}
// Send messages
if(!namesSuccess.isEmpty()) {
messageBridge.message(sender, "del-success", Utils.createCommaSeparatedList(namesSuccess));
}
if(!regionsFailed.isEmpty()) {
messageBridge.message(sender, "del-failed", Utils.combinedMessage(regionsFailed, "region"));
}
if(!regionsCancelled.isEmpty()) {
messageBridge.message(sender, "del-cancelled", Utils.combinedMessage(regionsCancelled, "region"));
}
} else {
GeneralRegion region = fileManager.getRegion(args[1]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[1]);
return;
}
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId());
if(region instanceof RentRegion) {
// Remove the rent if the player has permission
if(sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
if (event.isCancelled()) {
messageBridge.message(sender, "general-cancelled", event.getReason());
} else {
messageBridge.message(sender, "destroy-successRent", region);
}
} else {
messageBridge.message(sender, "destroy-noPermissionRent", region);
}
} else if(region instanceof BuyRegion) {
// Remove the buy if the player has permission
if(sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
if (event.isCancelled()) {
messageBridge.message(sender, "general-cancelled", event.getReason());
} else {
messageBridge.message(sender, "destroy-successBuy", region);
}
} else {
messageBridge.message(sender, "destroy-noPermissionBuy", region);
}
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = fileManager.getRegionNames();
}
return result;
}
}
@@ -0,0 +1,149 @@
package me.wiefferink.areashop.commands;
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.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 IFileManager fileManager;
@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 player = (Player)person;
return region.isOwner(player) && player.hasPermission("areashop.delfriend");
}
return false;
}
@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 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;
}
}
@@ -0,0 +1,92 @@
package me.wiefferink.areashop.commands;
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;
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;
@Singleton
public class DelsignCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private SignManager signManager;
@Override
public String getCommandStart() {
return "areashop delsign";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.delsign")) {
return "help-delsign";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.delsign")) {
messageBridge.message(sender, "delsign-noPermission");
return;
}
if(!(sender instanceof 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) {
block = next;
}
}
if(block == null || !Materials.isSign(block.getType())) {
messageBridge.message(sender, "delsign-noSign");
return;
}
Optional<RegionSign> optionalSign = signManager.removeSign(block.getLocation());
if(optionalSign.isEmpty()) {
messageBridge.message(sender, "delsign-noRegion");
return;
}
RegionSign regionSign = optionalSign.get();
messageBridge.message(sender, "delsign-success", regionSign.getRegion());
signManager.removeSign(regionSign);
regionSign.remove();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
}
}
@@ -0,0 +1,205 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.RegionGroup;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
import 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;
@Singleton
public class FindCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private Economy economy;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop find";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.find")) {
return "help-find";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.find")) {
messageBridge.message(sender, "find-noPermission");
return;
}
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
if(args.length <= 1 || args[1] == null || (!args[1].equalsIgnoreCase("buy") && !args[1].equalsIgnoreCase("rent"))) {
messageBridge.message(sender, "find-help");
return;
}
Player player = (Player)sender;
double balance = 0.0;
if(economy != null) {
balance = economy.getBalance(player);
}
double maxPrice = 0;
boolean maxPriceSet = false;
RegionGroup group = null;
// Parse optional price argument
if(args.length >= 3) {
try {
maxPrice = Double.parseDouble(args[2]);
maxPriceSet = true;
} catch(NumberFormatException e) {
messageBridge.message(sender, "find-wrongMaxPrice", args[2]);
return;
}
}
// Parse optional group argument
if(args.length >= 4) {
group = fileManager.getGroup(args[3]);
if(group == null) {
messageBridge.message(sender, "find-wrongGroup", args[3]);
return;
}
}
// Find buy regions
if(args[1].equalsIgnoreCase("buy")) {
Collection<BuyRegion> regions = fileManager.getBuysRef();
List<BuyRegion> results = new LinkedList<>();
for(BuyRegion region : regions) {
if(!region.isSold()
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
&& (group == null || group.isMember(region))
&& (region.getBooleanSetting("general.findCrossWorld") || player.getWorld().equals(region.getWorld()))) {
results.add(region);
}
}
if(!results.isEmpty()) {
// Draw a random one
BuyRegion region = results.get(new Random().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
}
// Teleport
if(maxPriceSet) {
messageBridge.message(player, "find-successMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup, region);
} else {
messageBridge.message(player, "find-success", "buy", Utils.formatCurrency(balance), onlyInGroup, region);
}
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else {
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
}
if(maxPriceSet) {
messageBridge.message(player, "find-noneFoundMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup);
} else {
messageBridge.message(player, "find-noneFound", "buy", Utils.formatCurrency(balance), onlyInGroup);
}
}
}
// Find rental regions
else {
Collection<RentRegion> regions = fileManager.getRentsRef();
List<RentRegion> results = new LinkedList<>();
for(RentRegion region : regions) {
if(!region.isRented()
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
&& (group == null || group.isMember(region))
&& (region.getBooleanSetting("general.findCrossWorld") || player.getWorld().equals(region.getWorld()))) {
results.add(region);
}
}
if(!results.isEmpty()) {
// Draw a random one
RentRegion region = results.get(new Random().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
}
// Teleport
if(maxPriceSet) {
messageBridge.message(player, "find-successMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup, region);
} else {
messageBridge.message(player, "find-success", "rent", Utils.formatCurrency(balance), onlyInGroup, region);
}
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else {
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
}
if(maxPriceSet) {
messageBridge.message(player, "find-noneFoundMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup);
} else {
messageBridge.message(player, "find-noneFound", "rent", Utils.formatCurrency(balance), onlyInGroup);
}
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.add("buy");
result.add("rent");
}
return result;
}
}
@@ -0,0 +1,130 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
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;
@Singleton
public class GroupaddCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private RegionFactory regionFactory;
@Inject
private WorldEditInterface worldEditInterface;
@Override
public String getCommandStart() {
return "areashop groupadd";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.groupadd")) {
return "help-groupadd";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupadd")) {
messageBridge.message(sender, "groupadd-noPermission");
return;
}
if(args.length < 2 || args[1] == null) {
messageBridge.message(sender, "groupadd-help");
return;
}
RegionGroup group = fileManager.getGroup(args[1]);
if(group == null) {
group = regionFactory.createRegionGroup(args[1]);
fileManager.addGroup(group);
}
if(args.length == 2) {
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
if(regions.isEmpty()) {
messageBridge.message(player, "cmd-noRegionsFound");
return;
}
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
for(GeneralRegion region : regions) {
if(group.addMember(region)) {
regionsSuccess.add(region);
} else {
regionsFailed.add(region);
}
}
if(!regionsSuccess.isEmpty()) {
messageBridge.message(player, "groupadd-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
}
if(!regionsFailed.isEmpty()) {
messageBridge.message(player, "groupadd-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
}
// Update all regions, this does it in a task, updating them without lag
fileManager.updateRegions(new ArrayList<>(regionsSuccess), player);
} else {
GeneralRegion region = fileManager.getRegion(args[2]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
if(group.addMember(region)) {
region.update();
messageBridge.message(sender, "groupadd-success", group.getName(), group.getMembers().size(), region);
} else {
messageBridge.message(sender, "groupadd-failed", group.getName(), region);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = fileManager.getGroupNames();
} else if(toComplete == 3) {
result = fileManager.getRegionNames();
}
return result;
}
}
@@ -0,0 +1,131 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
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;
@Singleton
public class GroupdelCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private RegionFactory regionFactory;
@Inject
private WorldEditInterface worldEditInterface;
@Override
public String getCommandStart() {
return "areashop groupdel";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.groupdel")) {
return "help-groupdel";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupdel")) {
messageBridge.message(sender, "groupdel-noPermission");
return;
}
if(args.length < 2 || args[1] == null) {
messageBridge.message(sender, "groupdel-help");
return;
}
RegionGroup group = fileManager.getGroup(args[1]);
if(group == null) {
messageBridge.message(sender, "groupdel-wrongGroup", args[1]);
return;
}
if(args.length == 2) {
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-weOnlyByPlayer");
return;
}
Player player = (Player)sender;
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
if(regions.isEmpty()) {
messageBridge.message(player, "cmd-noRegionsFound");
return;
}
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
for(GeneralRegion region : regions) {
if(group.removeMember(region)) {
regionsSuccess.add(region);
} else {
regionsFailed.add(region);
}
}
if(!regionsSuccess.isEmpty()) {
messageBridge.message(player, "groupdel-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
}
if(!regionsFailed.isEmpty()) {
messageBridge.message(player, "groupdel-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
}
// Update all regions, this does it in a task, updating them without lag
fileManager.updateRegions(regionsSuccess, player);
group.saveRequired();
} else {
GeneralRegion region = fileManager.getRegion(args[2]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[2]);
return;
}
if(group.removeMember(region)) {
region.update();
messageBridge.message(sender, "groupdel-success", group.getName(), group.getMembers().size(), region);
} else {
messageBridge.message(sender, "groupdel-failed", group.getName(), region);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = fileManager.getGroupNames();
} else if(toComplete == 3) {
result = fileManager.getRegionNames();
}
return result;
}
}
@@ -0,0 +1,79 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class GroupinfoCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop groupinfo";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.groupinfo")) {
return "help-groupinfo";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupinfo")) {
messageBridge.message(sender, "groupinfo-noPermission");
return;
}
if(args.length < 2 || args[1] == null) {
messageBridge.message(sender, "groupinfo-help");
return;
}
RegionGroup group = fileManager.getGroup(args[1]);
if(group == null) {
messageBridge.message(sender, "groupinfo-noGroup", args[1]);
return;
}
Set<String> members = group.getMembers();
if(members.isEmpty()) {
messageBridge.message(sender, "groupinfo-noMembers", group.getName());
} else {
messageBridge.message(sender, "groupinfo-members", group.getName(), Utils.createCommaSeparatedList(members));
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = fileManager.getGroupNames();
}
return result;
}
}
@@ -0,0 +1,63 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class GrouplistCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop grouplist";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.grouplist")) {
return "help-grouplist";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.grouplist")) {
messageBridge.message(sender, "grouplist-noPermission");
return;
}
List<String> groups = fileManager.getGroupNames();
if(groups.isEmpty()) {
messageBridge.message(sender, "grouplist-noGroups");
} else {
messageBridge.message(sender, "grouplist-success", Utils.createCommaSeparatedList(groups));
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
}
}
@@ -0,0 +1,35 @@
package me.wiefferink.areashop.commands;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import me.wiefferink.areashop.managers.CommandManager;
import org.bukkit.command.CommandSender;
import javax.annotation.Nonnull;
public class HelpCommand extends CommandAreaShop {
private final CommandManager commandManager;
public HelpCommand(@Nonnull CommandManager commandManager) {
this.commandManager = commandManager;
}
@Override
public String getCommandStart() {
return "areashop help";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.help")) {
return "help-help";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
commandManager.showHelp(sender);
}
}
@@ -0,0 +1,89 @@
package me.wiefferink.areashop.commands;
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;
@Singleton
public class ImportCommand extends CommandAreaShop {
/* RegionGroup priority usage:
0: Settings from /config.yml
1: Settings from /worlds/<world>/config.yml
2: Settings from /worlds/<world>/parent-regions.yml (if their priority is set it is added to this value)
*/
@Inject
private MessageBridge messageBridge;
@Inject
private ImportJobFactory importJobFactory;
@Override
public String getCommandStart() {
return "areashop import";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.import")) {
return "help-import";
}
return null;
}
// TODO:
// - Landlord?
// - Friends
// - Region flags?
// - Settings from the 'permissions' section in RegionForSale/config.yml?
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.import")) {
messageBridge.message(sender, "import-noPermission");
return;
}
if(args.length < 2) {
messageBridge.message(sender, "import-help");
return;
}
if(!"RegionForSale".equalsIgnoreCase(args[1])) {
messageBridge.message(sender, "import-wrongSource");
return;
}
if(!confirm(sender, args, Message.fromKey("import-confirm"))) {
return;
}
importJobFactory.createImportJob(sender).execute();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.add("RegionForSale");
}
return result;
}
}
@@ -0,0 +1,494 @@
package me.wiefferink.areashop.commands;
import io.github.bakedlibs.dough.blocks.BlockPosition;
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.RegionGroup;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
// TODO fix '/as info' help message hitting replacement limit (improve depth tracking?)
// TODO add info about autoExtend
@Singleton
public class InfoCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop info";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.info")) {
return "help-info";
}
return null;
}
/**
* Display a page of a list of regions.
* @param sender The CommandSender to send the messages to
* @param regions The regions to display
* @param filterGroup The group to filter the regions by
* @param keyHeader The header to print above the page
* @param pageInput The page number, if any
* @param baseCommand The command to execute for next/previous page (/areashop will be added)
*/
private void showSortedPagedList(CommandSender sender, List<? extends GeneralRegion> regions, RegionGroup filterGroup, String keyHeader, String pageInput, String baseCommand) {
int maximumItems = 20;
int itemsPerPage = maximumItems - 2;
int page = 1;
if(pageInput != null && Utils.isNumeric(pageInput)) {
try {
page = Integer.parseInt(pageInput);
} catch(NumberFormatException e) {
messageBridge.message(sender, "info-wrongPage", pageInput);
return;
}
}
if(filterGroup != null) {
regions.removeIf(generalRegion -> !filterGroup.isMember(generalRegion));
}
if(regions.isEmpty()) {
messageBridge.message(sender, "info-noRegions");
} else {
// First sort by type, then by name
regions.sort((one, two) -> {
int typeCompare = getTypeOrder(two).compareTo(getTypeOrder(one));
if(typeCompare != 0) {
return typeCompare;
} else {
return one.getName().compareTo(two.getName());
}
});
// Header
Message limitedToGroup = Message.empty();
if(filterGroup != null) {
limitedToGroup = Message.fromKey("info-limitedToGroup").replacements(filterGroup.getName());
}
messageBridge.message(sender, keyHeader, limitedToGroup);
// Page entries
int totalPages = (int)Math.ceil(regions.size() / (double)itemsPerPage); // Clip page to correct boundaries, not much need to tell the user
if(regions.size() == itemsPerPage + 1) { // 19 total items is mapped to 1 page of 19
itemsPerPage++;
totalPages = 1;
}
page = Math.max(1, Math.min(totalPages, page));
int linesPrinted = 1; // header
for(int i = (page - 1) * itemsPerPage; i < page * itemsPerPage && i < regions.size(); i++) {
String state;
GeneralRegion region = regions.get(i);
if(region.getType() == GeneralRegion.RegionType.RENT) {
if(region.getOwner() == null) {
state = "Forrent";
} else {
state = "Rented";
}
} else {
if(region.getOwner() == null) {
state = "Forsale";
} else if(!((BuyRegion)region).isInResellingMode()) {
state = "Sold";
} else {
state = "Reselling";
}
}
messageBridge.messageNoPrefix(sender, "info-entry" + state, region);
linesPrinted++;
}
Message footer = Message.empty();
// Previous button
if(page > 1) {
footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand + " " + (page - 1)));
} else {
footer.append(Message.fromKey("info-pageNoPrevious"));
}
// Page status
if(totalPages > 1) {
StringBuilder pageString = new StringBuilder("" + page);
for(int i = pageString.length(); i < (totalPages + "").length(); i++) {
pageString.insert(0, "0");
}
footer.append(Message.fromKey("info-pageStatus").replacements(page, totalPages));
if(page < totalPages) {
footer.append(Message.fromKey("info-pageNext").replacements(baseCommand + " " + (page + 1)));
} else {
footer.append(Message.fromKey("info-pageNoNext"));
}
// Fill up space if the page is not full (aligns header nicely)
for(int i = linesPrinted; i < maximumItems - 1; i++) {
sender.sendMessage(" ");
}
footer.send(sender);
}
}
}
/**
* Get an integer to order by type, usable for Comparators.
* @param region The region to get the order for
* @return An integer for sorting by type
*/
private Integer getTypeOrder(GeneralRegion region) {
if(region.getType() == GeneralRegion.RegionType.RENT) {
if(region.getOwner() == null) {
return 1;
} else {
return 2;
}
} else {
if(region.getOwner() == null) {
return 3;
} else if(!((BuyRegion)region).isInResellingMode()) {
return 4;
} else {
return 5;
}
}
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.info")) {
messageBridge.message(sender, "info-noPermission");
return;
}
if(args.length > 1 && args[1] != null) {
// Get filter group (only used by some commands)
RegionGroup filterGroup = null;
Set<String> groupFilters = new HashSet<>(Arrays.asList("all", "rented", "forrent", "sold", "forsale", "reselling"));
if(groupFilters.contains(args[1].toLowerCase()) && args.length > 2) {
if(!Utils.isNumeric(args[2])) {
filterGroup = fileManager.getGroup(args[2]);
if(filterGroup == null) {
messageBridge.message(sender, "info-noFiltergroup", args[2]);
return;
}
// Pass page number to args[2] if available
if(args.length > 3) {
args[2] = args[3];
}
}
}
// All regions
if(args[1].equalsIgnoreCase("all")) {
showSortedPagedList(sender, new ArrayList<>(fileManager.getRegionsRef()), filterGroup, "info-allHeader", (args.length > 2 ? args[2] : null), "info all");
}
// Rented regions
else if(args[1].equalsIgnoreCase("rented")) {
List<RentRegion> regions = new ArrayList<>(fileManager.getRentsRef());
regions.removeIf(RentRegion::isAvailable);
showSortedPagedList(sender, regions, filterGroup, "info-rentedHeader", (args.length > 2 ? args[2] : null), "info rented");
}
// Forrent regions
else if(args[1].equalsIgnoreCase("forrent")) {
List<RentRegion> regions = new ArrayList<>(fileManager.getRentsRef());
regions.removeIf(RentRegion::isRented);
showSortedPagedList(sender, regions, filterGroup, "info-forrentHeader", (args.length > 2 ? args[2] : null), "info forrent");
}
// Sold regions
else if(args[1].equalsIgnoreCase("sold")) {
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
regions.removeIf(BuyRegion::isAvailable);
showSortedPagedList(sender, regions, filterGroup, "info-soldHeader", (args.length > 2 ? args[2] : null), "info sold");
}
// Forsale regions
else if(args[1].equalsIgnoreCase("forsale")) {
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
regions.removeIf(BuyRegion::isSold);
showSortedPagedList(sender, regions, filterGroup, "info-forsaleHeader", (args.length > 2 ? args[2] : null), "info forsale");
}
// Reselling regions
else if(args[1].equalsIgnoreCase("reselling")) {
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
regions.removeIf(region -> !region.isInResellingMode());
showSortedPagedList(sender, regions, filterGroup, "info-resellingHeader", (args.length > 2 ? args[2] : null), "info reselling");
}
// List of regions without a group
else if(args[1].equalsIgnoreCase("nogroup")) {
List<GeneralRegion> regions = new ArrayList<>(fileManager.getRegionsRef());
for(RegionGroup group : fileManager.getGroups()) {
regions.removeAll(group.getMemberRegions());
}
if(regions.isEmpty()) {
messageBridge.message(sender, "info-nogroupNone");
} else {
showSortedPagedList(sender, regions, filterGroup, "info-nogroupHeader", (args.length > 2 ? args[2] : null), "info nogroup");
}
}
// Region info
else if(args[1].equalsIgnoreCase("region")) {
if(args.length > 1) {
RentRegion rent = null;
BuyRegion buy = null;
if(args.length > 2) {
rent = fileManager.getRent(args[2]);
buy = fileManager.getBuy(args[2]);
} else {
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 {
if(regions.get(0) instanceof RentRegion) {
rent = (RentRegion)regions.get(0);
} else if(regions.get(0) instanceof BuyRegion) {
buy = (BuyRegion)regions.get(0);
}
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
}
if(rent == null && buy == null) {
messageBridge.message(sender, "info-regionNotExisting", args[2]);
return;
}
if(rent != null) {
messageBridge.message(sender, "info-regionHeaderRent", rent);
if(rent.isRented()) {
messageBridge.messageNoPrefix(sender, "info-regionRented", rent);
messageBridge.messageNoPrefix(sender, "info-regionExtending", rent);
// Money back
if(UnrentCommand.canUse(sender, rent)) {
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackRentClick", rent);
} else {
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackRent", rent);
}
// Friends
if(!rent.getFriendsFeature().getFriendNames().isEmpty()) {
String messagePart = "info-friend";
if(DelfriendCommand.canUse(sender, rent)) {
messagePart = "info-friendRemove";
}
messageBridge.messageNoPrefix(sender, "info-regionFriends", rent, Utils.combinedMessage(rent.getFriendsFeature().getFriendNames(), messagePart));
}
} else {
messageBridge.messageNoPrefix(sender, "info-regionCanBeRented", rent);
}
if(rent.getLandlordName() != null) {
messageBridge.messageNoPrefix(sender, "info-regionLandlord", rent);
}
// Maximum extends
if(rent.getMaxExtends() != -1) {
if(rent.getMaxExtends() == 0) {
messageBridge.messageNoPrefix(sender, "info-regionNoExtending", rent);
} else if(rent.isRented()) {
messageBridge.messageNoPrefix(sender, "info-regionExtendsLeft", rent);
} else {
messageBridge.messageNoPrefix(sender, "info-regionMaxExtends", rent);
}
}
// If maxExtends is zero it does not make sense to show this message
if(rent.getMaxRentTime() != -1 && rent.getMaxExtends() != 0) {
messageBridge.messageNoPrefix(sender, "info-regionMaxRentTime", rent);
}
if(rent.getInactiveTimeUntilUnrent() != -1) {
messageBridge.messageNoPrefix(sender, "info-regionInactiveUnrent", rent);
}
// Teleport
Message tp = Message.fromKey("info-prefix");
boolean foundSomething = false;
if(TeleportCommand.canUse(sender, rent)) {
foundSomething = true;
tp.append(Message.fromKey("info-regionTeleport").replacements(rent));
}
if(SetteleportCommand.canUse(sender, rent)) {
if(foundSomething) {
tp.append(", ");
}
foundSomething = true;
tp.append(Message.fromKey("info-setRegionTeleport").replacements(rent));
}
if(foundSomething) {
tp.append(".");
tp.send(sender);
}
// Signs
List<String> signLocations = new ArrayList<>();
for(BlockPosition location : rent.getSignsFeature().signManager().allSignLocations()) {
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getX(), location.getY(), location.getZ()).getPlain());
}
if(!signLocations.isEmpty()) {
messageBridge.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
}
// Groups
if(sender.hasPermission("areashop.groupinfo") && !rent.getGroupNames().isEmpty()) {
messageBridge.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(rent.getGroupNames()));
}
// Restoring
if(rent.isRestoreEnabled()) {
messageBridge.messageNoPrefix(sender, "info-regionRestoringRent", rent);
}
// Restrictions
if(!rent.isRented()) {
if(rent.restrictedToRegion()) {
messageBridge.messageNoPrefix(sender, "info-regionRestrictedRegionRent", rent);
} else if(rent.restrictedToWorld()) {
messageBridge.messageNoPrefix(sender, "info-regionRestrictedWorldRent", rent);
}
}
messageBridge.messageNoPrefix(sender, "info-regionFooterRent", rent);
} else if(buy != null) {
messageBridge.message(sender, "info-regionHeaderBuy", buy);
if(buy.isSold()) {
if(buy.isInResellingMode()) {
messageBridge.messageNoPrefix(sender, "info-regionReselling", buy);
messageBridge.messageNoPrefix(sender, "info-regionReselPrice", buy);
} else {
messageBridge.messageNoPrefix(sender, "info-regionBought", buy);
}
// Money back
if(!buy.getBooleanSetting("buy.sellDisabled")) {
if (SellCommand.canUse(sender, buy)) {
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackBuyClick", buy);
} else {
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackBuy", buy);
}
}
// Friends
if(!buy.getFriendsFeature().getFriendNames().isEmpty()) {
String messagePart = "info-friend";
if(DelfriendCommand.canUse(sender, buy)) {
messagePart = "info-friendRemove";
}
messageBridge.messageNoPrefix(sender, "info-regionFriends", buy, Utils.combinedMessage(buy.getFriendsFeature().getFriendNames(), messagePart));
}
} else {
messageBridge.messageNoPrefix(sender, "info-regionCanBeBought", buy);
}
if(buy.getLandlord() != null) {
messageBridge.messageNoPrefix(sender, "info-regionLandlord", buy);
}
if(buy.getInactiveTimeUntilSell() != -1) {
messageBridge.messageNoPrefix(sender, "info-regionInactiveSell", buy);
}
// Teleport
Message tp = Message.fromKey("info-prefix");
boolean foundSomething = false;
if(TeleportCommand.canUse(sender, buy)) {
foundSomething = true;
tp.append(Message.fromKey("info-regionTeleport").replacements(buy));
}
if(SetteleportCommand.canUse(sender, buy)) {
if(foundSomething) {
tp.append(", ");
}
foundSomething = true;
tp.append(Message.fromKey("info-setRegionTeleport").replacements(buy));
}
if(foundSomething) {
tp.append(".");
tp.send(sender);
}
// Signs
List<String> signLocations = new ArrayList<>();
for(BlockPosition location : buy.getSignsFeature().signManager().allSignLocations()) {
signLocations.add(Message.fromKey("info-regionSignLocation").replacements(location.getWorld().getName(), location.getX(), location.getY(), location.getZ()).getPlain());
}
if(!signLocations.isEmpty()) {
messageBridge.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
}
// Groups
if(sender.hasPermission("areashop.groupinfo") && !buy.getGroupNames().isEmpty()) {
messageBridge.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(buy.getGroupNames()));
}
// Restoring
if(buy.isRestoreEnabled()) {
messageBridge.messageNoPrefix(sender, "info-regionRestoringBuy", buy);
}
// Restrictions
if(!buy.isSold()) {
if(buy.restrictedToRegion()) {
messageBridge.messageNoPrefix(sender, "info-regionRestrictedRegionBuy", buy);
} else if(buy.restrictedToWorld()) {
messageBridge.messageNoPrefix(sender, "info-regionRestrictedWorldBuy", buy);
}
}
messageBridge.messageNoPrefix(sender, "info-regionFooterBuy", buy);
}
} else {
messageBridge.message(sender, "info-regionHelp");
}
} else {
messageBridge.message(sender, "info-help");
}
} else {
messageBridge.message(sender, "info-help");
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(Arrays.asList("all", "rented", "forrent", "sold", "forsale", "player", "region", "nogroup", "reselling"));
} else if(toComplete == 3) {
if(start[2].equalsIgnoreCase("player")) {
for(Player player : Utils.getOnlinePlayers()) {
result.add(player.getName());
}
} else if(start[2].equalsIgnoreCase("region")) {
result.addAll(fileManager.getBuyNames());
result.addAll(fileManager.getRentNames());
}
}
return result;
}
}
@@ -0,0 +1,100 @@
package me.wiefferink.areashop.commands;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Singleton
public class LinksignsCommand extends CommandAreaShop {
@Inject
private SignLinkerManager signLinkerManager;
@Inject
private AreaShop plugin;
@Inject
private MessageBridge messageBridge;
@Override
public String getCommandStart() {
return "areashop linksigns";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.linksigns")) {
return "help-linksigns";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.linksigns")) {
messageBridge.message(sender, "linksigns-noPermission");
return;
}
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(signLinkerManager.isInSignLinkMode(player)) {
signLinkerManager.exitSignLinkMode(player);
} else {
// Get the profile
String profile = null;
if(args.length > 1) {
profile = args[1];
ConfigurationSection signProfilesSection = plugin.getConfig().getConfigurationSection("signProfiles");
if(signProfilesSection != null) {
Set<String> profiles = signProfilesSection.getKeys(false);
if(!profiles.contains(profile)) {
ArrayList<String> message = new ArrayList<>();
for(String p : profiles) {
if(!message.isEmpty()) {
message.add(", ");
}
message.addAll(Message.fromKey("addsign-profile").replacements(p).get());
}
messageBridge.message(sender, "addsign-wrongProfile", Message.fromList(message));
return;
}
}
}
signLinkerManager.enterSignLinkMode(player, profile);
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
result.addAll(plugin.getConfig().getStringList("signProfiles"));
}
return result;
}
}
@@ -0,0 +1,153 @@
package me.wiefferink.areashop.commands;
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.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;
import java.util.Set;
@Singleton
public class MeCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop me";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.me")) {
return "help-me";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.me")) {
messageBridge.message(sender, "me-noPermission");
return;
}
OfflinePlayer player = null;
if(!(sender instanceof Player)) {
if(args.length <= 1) {
messageBridge.message(sender, "me-notAPlayer");
return;
}
} else {
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()) {
return;
}
// Get the regions owned by the player
Set<RentRegion> rentRegions = new HashSet<>();
for(RentRegion region : fileManager.getRentsRef()) {
if(region.isOwner(player)) {
rentRegions.add(region);
}
}
Set<BuyRegion> buyRegions = new HashSet<>();
for(BuyRegion region : fileManager.getBuysRef()) {
if(region.isOwner(player)) {
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())) {
friendRegions.add(region);
}
}
// Send messages
boolean foundSome = !rentRegions.isEmpty() || !buyRegions.isEmpty() || !friendRegions.isEmpty();
if(foundSome) {
messageBridge.message(sender, "me-header", player.getName());
}
if(!rentRegions.isEmpty()) {
for(RentRegion region : rentRegions) {
messageBridge.messageNoPrefix(sender, "me-rentLine", region);
}
}
if(!buyRegions.isEmpty()) {
for(BuyRegion region : buyRegions) {
messageBridge.messageNoPrefix(sender, "me-buyLine", region);
}
}
if(!friendRegions.isEmpty()) {
for(GeneralRegion region : friendRegions) {
messageBridge.messageNoPrefix(sender, "me-friendLine", region);
}
}
if(!foundSome) {
messageBridge.message(sender, "me-nothing", player.getName());
} else {
messageBridge.messageNoPrefix(sender, "me-clickHint");
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(Player player : Utils.getOnlinePlayers()) {
result.add(player.getName());
}
}
return result;
}
}
@@ -0,0 +1,79 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class MessageCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Override
public String getCommandStart() {
return "areashop message";
}
@Override
public String getHelp(CommandSender target) {
// Internal command, no need to show in the help list
return null;
}
@Override
public void execute(final CommandSender sender, final String[] args) {
if(!sender.hasPermission("areashop.message")) {
messageBridge.message(sender, "message-noPermission");
return;
}
if(args.length < 3) {
messageBridge.message(sender, "message-help");
return;
}
Player player = Bukkit.getPlayer(args[1]);
if(player == null) {
messageBridge.message(sender, "message-notOnline", args[1]);
return;
}
String[] messageArgs = new String[args.length - 2];
System.arraycopy(args, 2, messageArgs, 0, args.length - 2);
String message = StringUtils.join(messageArgs, " ");
Message.fromString(message).send(player);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
for(Player player : Utils.getOnlinePlayers()) {
result.add(player.getName());
}
}
return result;
}
}
@@ -0,0 +1,7 @@
# Commands
This module contains all AreaShop commands.
* `CommandAreaShop` is extended by all other classes, and implements some general functionality and defines which methods should be implemented.
* Other classes implement specific sub-commands, supply their help messages and tab completion.
* `CommandManager` class in the `managers` package handles incoming commands and dispatches them to the classes in this package.
@@ -0,0 +1,40 @@
package me.wiefferink.areashop.commands;
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 {
@Inject
private AreaShop plugin;
@Inject
private MessageBridge messageBridge;
@Override
public String getCommandStart() {
return "areashop reload";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.reload")) {
return "help-reload";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(sender.hasPermission("areashop.reload")) {
// Reload the configuration files and update all region flags/signs
plugin.reload(sender);
} else {
messageBridge.message(sender, "reload-noPermission");
}
}
}
@@ -0,0 +1,79 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class RentCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop rent";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.rent")) {
return "help-rent";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.rent")) {
messageBridge.message(sender, "rent-noPermission");
return;
}
if(!(sender instanceof 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) {
messageBridge.message(sender, "rent-notRentable", args[1]);
} else {
rent.rent(player);
}
} else {
// get the region by location
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
} else {
regions.get(0).rent(player);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(RentRegion region : fileManager.getRentsRef()) {
if(!region.isRented()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,144 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class ResellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop resell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.resellall") || target.hasPermission("areashop.resell")) {
return "help-resell";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
messageBridge.message(sender, "resell-noPermissionOther");
return;
}
if(args.length <= 1) {
messageBridge.message(sender, "resell-help");
return;
}
double price;
try {
price = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
messageBridge.message(sender, "resell-wrongPrice", args[1]);
return;
}
if(price < 0) {
messageBridge.message(sender, "resell-wrongPrice", args[1]);
return;
}
BuyRegion buy;
if(args.length <= 2) {
if(sender instanceof Player) {
// get the region by location
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = fileManager.getBuy(args[2]);
if(buy == null) {
messageBridge.message(sender, "resell-notRegistered", args[2]);
return;
}
}
if(buy == null) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
}
if(!buy.isSold()) {
messageBridge.message(sender, "resell-notBought", buy);
return;
}
if(sender.hasPermission("areashop.resellall")) {
buy.enableReselling(price);
buy.update();
messageBridge.message(sender, "resell-success", buy);
} else if(sender.hasPermission("areashop.resell") && sender instanceof Player) {
if(!buy.isOwner((Player)sender)) {
messageBridge.message(sender, "resell-noPermissionOther", buy);
return;
}
if(buy.getBooleanSetting("buy.resellDisabled")) {
messageBridge.message(sender, "resell-disabled", buy);
return;
}
buy.enableReselling(price);
buy.update();
messageBridge.message(sender, "resell-success", buy);
} else {
messageBridge.message(sender, "resell-noPermission", buy);
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 3) {
for(BuyRegion region : fileManager.getBuysRef()) {
if(region.isSold() && !region.isInResellingMode()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,96 @@
package me.wiefferink.areashop.commands;
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.command.CommandSender;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Singleton
public class SchematiceventCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop schemevent";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.schematicevents")) {
return "help-schemevent";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.schematicevents")) {
messageBridge.message(sender, "schemevent-noPermission");
return;
}
if(args.length < 3 || args[1] == null || args[2] == null) {
messageBridge.message(sender, "schemevent-help");
return;
}
GeneralRegion region = fileManager.getRegion(args[1]);
if(region == null) {
messageBridge.message(sender, "cmd-notRegistered", args[1]);
return;
}
if(region.getRegion() == null) {
messageBridge.message(sender, "general-noRegion", region);
return;
}
GeneralRegion.RegionEvent event = null;
boolean exception = false;
try {
event = GeneralRegion.RegionEvent.valueOf(args[2].toUpperCase());
} catch(IllegalArgumentException e) {
exception = true;
}
// Check for a totally wrong event or a non matching event
if(exception) {
ArrayList<String> values = new ArrayList<>();
for(GeneralRegion.RegionEvent value : GeneralRegion.RegionEvent.values()) {
values.add(value.getValue().toLowerCase());
}
messageBridge.message(sender, "schemevent-wrongEvent", args[2], Utils.createCommaSeparatedList(values), region);
return;
}
region.handleSchematicEvent(event);
region.update();
messageBridge.message(sender, "schemevent-success", args[2], region);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(fileManager.getRegionNames());
} else if(toComplete == 3) {
GeneralRegion region = fileManager.getRegion(start[2]);
if(region != null) {
if(region instanceof RentRegion) {
result.addAll(Arrays.asList("created", "deleted", "rented", "unrented"));
} else if(region instanceof BuyRegion) {
result.addAll(Arrays.asList("created", "deleted", "bought", "sold"));
}
}
}
return result;
}
}
@@ -0,0 +1,120 @@
package me.wiefferink.areashop.commands;
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.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;
@Singleton
public class SellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop sell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.sell") || target.hasPermission("areashop.sellown")) {
return "help-sell";
}
return null;
}
/**
* Check if a person can sell the region.
* @param person The person to check
* @param region The region to check for
* @return true if the person can sell it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(person.hasPermission("areashop.sell")) {
return true;
}
if(person instanceof Player) {
Player player = (Player)person;
return region.isOwner(player) && person.hasPermission("areashop.sellown");
}
return false;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
messageBridge.message(sender, "sell-noPermission");
return;
}
BuyRegion buy;
if(args.length <= 1) {
if(sender instanceof Player) {
// get the region by location
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = fileManager.getBuy(args[1]);
}
if(buy == null) {
messageBridge.message(sender, "sell-notRegistered");
return;
}
if(!buy.isSold()) {
messageBridge.message(sender, "sell-notBought", buy);
return;
}
buy.sell(true, sender);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(BuyRegion region : fileManager.getBuysRef()) {
if(region.isSold()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,118 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class SetdurationCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop setduration";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setduration")) {
return "help-setduration";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setduration") && (!sender.hasPermission("areashop.setduration.landlord") && sender instanceof Player)) {
messageBridge.message(sender, "setduration-noPermission");
return;
}
if(args.length < 3 || args[1] == null || args[2] == null) {
messageBridge.message(sender, "setduration-help");
return;
}
int regionArgument = 3;
if(args.length >= 2 && ("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1]))) {
regionArgument = 2;
}
RentRegion rent;
if(args.length <= regionArgument) {
if(sender instanceof Player) {
// get the region by location
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
rent = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
rent = fileManager.getRent(args[regionArgument]);
}
if(rent == null) {
messageBridge.message(sender, "setduration-notRegistered", args[regionArgument]);
return;
}
if(!sender.hasPermission("areashop.setduration") && !(sender instanceof Player && rent.isLandlord(((Player)sender).getUniqueId()))) {
messageBridge.message(sender, "setduration-noLandlord", rent);
return;
}
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
rent.setDuration(null);
rent.update();
messageBridge.message(sender, "setduration-successRemoved", rent);
return;
}
try {
Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
messageBridge.message(sender, "setduration-wrongAmount", args[1], rent);
return;
}
if(!Utils.checkTimeFormat(args[1] + " " + args[2])) {
messageBridge.message(sender, "setduration-wrongFormat", args[1] + " " + args[2], rent);
return;
}
rent.setDuration(args[1] + " " + args[2]);
rent.update();
messageBridge.message(sender, "setduration-success", rent);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 3) {
result.addAll(plugin.getConfig().getStringList("minutes"));
result.addAll(plugin.getConfig().getStringList("hours"));
result.addAll(plugin.getConfig().getStringList("days"));
result.addAll(plugin.getConfig().getStringList("months"));
result.addAll(plugin.getConfig().getStringList("years"));
} else if(toComplete == 4) {
result = fileManager.getRentNames();
}
return result;
}
}
@@ -0,0 +1,97 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
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 IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop setlandlord";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setlandlord")) {
return "help-setlandlord";
}
return null;
}
@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 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;
}
}
@@ -0,0 +1,144 @@
package me.wiefferink.areashop.commands;
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.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;
import java.util.UUID;
@Singleton
public class SetownerCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop setowner";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
return "help-setowner";
}
return null;
}
@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;
}
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;
}
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;
}
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();
}
@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;
}
}
@@ -0,0 +1,113 @@
package me.wiefferink.areashop.commands;
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.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 SetpriceCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop setprice";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setprice")) {
return "help-setprice";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setprice") && (!sender.hasPermission("areashop.setprice.landlord") && sender instanceof Player)) {
messageBridge.message(sender, "setprice-noPermission");
return;
}
if(args.length < 2 || args[1] == null) {
messageBridge.message(sender, "setprice-help");
return;
}
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, "setprice-notRegistered", args[2]);
return;
}
if(!sender.hasPermission("areashop.setprice") && !(sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId()))) {
messageBridge.message(sender, "setprice-noLandlord", region);
return;
}
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
if(region instanceof RentRegion) {
((RentRegion)region).setPrice(null);
} else if(region instanceof BuyRegion) {
((BuyRegion)region).setPrice(null);
}
region.update();
messageBridge.message(sender, "setprice-successRemoved", region);
return;
}
double price;
try {
price = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
messageBridge.message(sender, "setprice-wrongPrice", args[1], region);
return;
}
if(region instanceof RentRegion) {
((RentRegion)region).setPrice(price);
messageBridge.message(sender, "setprice-successRent", region);
} else if(region instanceof BuyRegion) {
((BuyRegion)region).setPrice(price);
messageBridge.message(sender, "setprice-successBuy", region);
}
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 3) {
result = fileManager.getRegionNames();
}
return result;
}
}
@@ -0,0 +1,86 @@
package me.wiefferink.areashop.commands;
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 javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class SetrestoreCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop setrestore";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setrestore")) {
return "help-setrestore";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setrestore")) {
messageBridge.message(sender, "setrestore-noPermission");
return;
}
if(args.length <= 2 || args[1] == null || args[2] == null) {
messageBridge.message(sender, "setrestore-help");
return;
}
GeneralRegion region = fileManager.getRegion(args[1]);
if(region == null) {
messageBridge.message(sender, "setrestore-notRegistered", args[1]);
return;
}
Boolean value = null;
if(args[2].equalsIgnoreCase("true")) {
value = true;
} else if(args[2].equalsIgnoreCase("false")) {
value = false;
}
region.setRestoreSetting(value);
String valueString = "general";
if(value != null) {
valueString = value + "";
}
if(args.length > 3) {
region.setSchematicProfile(args[3]);
messageBridge.message(sender, "setrestore-successProfile", valueString, args[3], region);
} else {
messageBridge.message(sender, "setrestore-success", valueString, 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");
result.add("general");
} else if(toComplete == 4) {
result.addAll(plugin.getConfig().getConfigurationSection("schematicProfiles").getKeys(false));
}
return result;
}
}
@@ -0,0 +1,128 @@
package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
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.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 SetteleportCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop settp";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setteleportall") || target.hasPermission("areashop.setteleport")) {
return "help-setteleport";
}
return null;
}
/**
* Check if a person can set the teleport location of the region.
* @param person The person to check
* @param region The region to check for
* @return true if the person can set the teleport location, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(!(person instanceof Player)) {
return false;
}
Player player = (Player)person;
return player.hasPermission("areashop.setteleportall")
|| region.isOwner(player) && player.hasPermission("areashop.setteleport");
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setteleport") && !sender.hasPermission("areashop.setteleportall")) {
messageBridge.message(sender, "setteleport-noPermission");
return;
}
if(!(sender instanceof Player)) {
messageBridge.message(sender, "onlyByPlayer");
return;
}
Player player = (Player)sender;
GeneralRegion region;
if(args.length < 2) {
// 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 {
region = fileManager.getRegion(args[1]);
}
boolean owner;
if(region == null) {
messageBridge.message(player, "setteleport-noRentOrBuy", args[1]);
return;
}
if(region instanceof RentRegion) {
owner = player.getUniqueId().equals(((RentRegion)region).getRenter());
} else {
owner = player.getUniqueId().equals(((BuyRegion)region).getBuyer());
}
if(!player.hasPermission("areashop.setteleport")) {
messageBridge.message(player, "setteleport-noPermission", region);
return;
} else if(!owner && !player.hasPermission("areashop.setteleportall")) {
messageBridge.message(player, "setteleport-noPermissionOther", region);
return;
}
ProtectedRegion wgRegion = region.getRegion();
if(args.length > 2 && args[2] != null && (args[2].equalsIgnoreCase("reset") || args[2].equalsIgnoreCase("yes") || args[2].equalsIgnoreCase("true"))) {
region.getTeleportFeature().setTeleport(null);
region.update();
messageBridge.message(player, "setteleport-reset", region);
return;
}
if(!player.hasPermission("areashop.setteleportoutsideregion") && (wgRegion == null || !wgRegion.contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
messageBridge.message(player, "setteleport-notInside", region);
return;
}
region.getTeleportFeature().setTeleport(player.getLocation());
region.update();
messageBridge.message(player, "setteleport-success", region);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(fileManager.getRegionNames());
} else if(toComplete == 3) {
result.add("reset");
}
return result;
}
}
@@ -0,0 +1,283 @@
package me.wiefferink.areashop.commands;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
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.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RegionGroup;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.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;
@Singleton
public class StackCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Inject
private WorldEditInterface worldEditInterface;
@Inject
private WorldGuardInterface worldGuardInterface;
@Inject
private RegionFactory regionFactory;
@Inject
private Plugin plugin;
@Override
public String getCommandStart() {
return "areashop stack";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.stack")) {
return "help-stack";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
// Check permission
if(!sender.hasPermission("areashop.stack")) {
messageBridge.message(sender, "stack-noPermission");
return;
}
// Only from ingame
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
final Player player = (Player)sender;
// Specify enough arguments
if(args.length < 5) {
messageBridge.message(sender, "stack-help");
return;
}
// Check amount
int tempAmount = -1;
try {
tempAmount = Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
// Incorrect number
}
if(tempAmount <= 0) {
messageBridge.message(player, "stack-wrongAmount", args[1]);
return;
}
// Check gap
int gap;
try {
gap = Integer.parseInt(args[2]);
} catch(NumberFormatException e) {
messageBridge.message(player, "stack-wrongGap", args[2]);
return;
}
// Check region type
if(!"rent".equalsIgnoreCase(args[4]) && !"buy".equalsIgnoreCase(args[4])) {
messageBridge.message(sender, "stack-help");
return;
}
// Get WorldEdit selection
final WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
if(selection == null) {
messageBridge.message(player, "stack-noSelection");
return;
}
// Get or create group
RegionGroup group = null;
if(args.length > 5) {
group = fileManager.getGroup(args[5]);
if(group == null) {
group = regionFactory.createRegionGroup(args[5]);
fileManager.addGroup(group);
}
}
// Get facing of the player (must be clearly one of the four directions to make sure it is no mistake)
BlockFace facing = Utils.yawToFacing(player.getLocation().getYaw());
if(player.getLocation().getPitch() > 45) {
facing = BlockFace.DOWN;
} else if(player.getLocation().getPitch() < -45) {
facing = BlockFace.UP;
}
if(!(facing == BlockFace.NORTH || facing == BlockFace.EAST || facing == BlockFace.SOUTH || facing == BlockFace.WEST || facing == BlockFace.UP || facing == BlockFace.DOWN)) {
messageBridge.message(player, "stack-unclearDirection", facing.toString().toLowerCase().replace('_', '-'));
return;
}
Vector shift = new Vector(0, 0, 0);
if(facing == BlockFace.SOUTH) {
shift = shift.setZ(-selection.getLength() - gap);
} else if(facing == BlockFace.WEST) {
shift = shift.setX(selection.getWidth() + gap);
} else if(facing == BlockFace.NORTH) {
shift = shift.setZ(selection.getLength() + gap);
} else if(facing == BlockFace.EAST) {
shift = shift.setX(-selection.getWidth() - gap);
} else if(facing == BlockFace.DOWN) {
shift = shift.setY(-selection.getHeight() - gap);
} else if(facing == BlockFace.UP) {
shift = shift.setY(selection.getHeight() + gap);
}
AreaShop.debug(" calculated shift vector: " + shift + ", with facing=" + facing);
// Create regions and add them to AreaShop
final String nameTemplate = args[3];
final int regionsPerTick = plugin.getConfig().getInt("adding.regionsPerTick");
final boolean rentRegions = "rent".equalsIgnoreCase(args[4]);
final int amount = tempAmount;
final RegionGroup finalGroup = group;
final Vector finalShift = shift;
String type;
if(rentRegions) {
type = "rent";
} else {
type = "buy";
}
Message groupsMessage = Message.empty();
if(group != null) {
groupsMessage = Message.fromKey("stack-addToGroup").replacements(group.getName());
}
messageBridge.message(player, "stack-accepted", amount, type, gap, nameTemplate, groupsMessage);
messageBridge.message(player, "stack-addStart", amount, regionsPerTick * 20);
Location minimumLocation = selection.getMinimumLocation();
Vector minimumVector = new Vector(minimumLocation.getX(), minimumLocation.getY(), minimumLocation.getZ());
Location maximumLocation = selection.getMaximumLocation();
Vector maximumVector = new Vector(maximumLocation.getX(), maximumLocation.getY(), maximumLocation.getZ());
new BukkitRunnable() {
private int current = -1;
private final RegionManager manager = AreaShop.getInstance().getRegionManager(selection.getWorld());
private int counter = 1;
private int tooLow = 0;
private int tooHigh = 0;
@Override
public void run() {
for(int i = 0; i < regionsPerTick; i++) {
current++;
if(current < amount) {
// Create the region name
String regionName = countToName(nameTemplate, counter);
while(manager.getRegion(regionName) != null || AreaShop.getInstance().getFileManager().getRegion(regionName) != null) {
counter++;
regionName = countToName(nameTemplate, counter);
}
// Add the region to WorldGuard (at startposition shifted by the number of this region times the blocks it should shift)
Vector minimum = minimumVector.clone().add(finalShift.clone().multiply(current));
Vector maximum = maximumVector.clone().add(finalShift.clone().multiply(current));
// Check for out of bounds
if(minimum.getBlockY() < 0) {
tooLow++;
continue;
} else if(maximum.getBlockY() > 256) {
tooHigh++;
continue;
}
ProtectedCuboidRegion region = worldGuardInterface.createCuboidRegion(regionName, minimum,maximum);
manager.addRegion(region);
// Add the region to AreaShop
GeneralRegion newRegion;
if(rentRegions) {
newRegion = regionFactory.createRentRegion(regionName, selection.getWorld());
} else {
newRegion = regionFactory.createBuyRegion(regionName, selection.getWorld());
}
if(finalGroup != null) {
finalGroup.addMember(newRegion);
}
AddingRegionEvent event = fileManager.addRegion(newRegion);
if (event.isCancelled()) {
messageBridge.message(player, "general-cancelled", event.getReason());
continue;
}
newRegion.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
newRegion.update();
}
}
if(current >= amount) {
if(player.isOnline()) {
int added = amount - tooLow - tooHigh;
Message wrong = Message.empty();
if(tooHigh > 0) {
wrong.append(Message.fromKey("stack-tooHigh").replacements(tooHigh));
}
if(tooLow > 0) {
wrong.append(Message.fromKey("stack-tooLow").replacements(tooLow));
}
messageBridge.message(player, "stack-addComplete", added, wrong);
}
this.cancel();
}
}
}.runTaskTimer(plugin, 1, 1);
}
/**
* Build a name from a count, with the right length.
* @param template Template to put the name in (# to put the count there, otherwise count is appended)
* @param count Number to use
* @return name with prepended 0's
*/
private String countToName(String template, int count) {
StringBuilder counterName = new StringBuilder().append(count);
int minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
while(counterName.length() < minimumLength) {
counterName.insert(0, "0");
}
if(template.contains("#")) {
return template.replace("#", counterName);
} else {
return template + counterName;
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 5) {
result.add("rent");
result.add("buy");
} else if(toComplete == 6) {
result.addAll(fileManager.getGroupNames());
}
return result;
}
}
@@ -0,0 +1,121 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class StopresellCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop stopresell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.stopresellall") || target.hasPermission("areashop.stopresell")) {
return "help-stopResell";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
messageBridge.message(sender, "stopresell-noPermissionOther");
return;
}
BuyRegion buy;
if(args.length <= 1) {
if(sender instanceof Player) {
// get the region by location
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = fileManager.getBuy(args[1]);
if(buy == null) {
messageBridge.message(sender, "stopresell-notRegistered", args[1]);
return;
}
}
if(buy == null) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
}
if(!buy.isInResellingMode()) {
messageBridge.message(sender, "stopresell-notResell", buy);
return;
}
if(sender.hasPermission("areashop.stopresellall")) {
buy.disableReselling();
buy.update();
messageBridge.message(sender, "stopresell-success", buy);
} else if(sender.hasPermission("areashop.stopresell") && sender instanceof Player) {
if(buy.isOwner((Player)sender)) {
buy.disableReselling();
buy.update();
messageBridge.message(sender, "stopresell-success", buy);
} else {
messageBridge.message(sender, "stopresell-noPermissionOther", buy);
}
} else {
messageBridge.message(sender, "stopresell-noPermission", buy);
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(BuyRegion region : fileManager.getBuysRef()) {
if(region.isSold() && region.isInResellingMode()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,92 @@
package me.wiefferink.areashop.commands;
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.entity.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class TeleportCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop tp";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
return "help-teleport";
}
return null;
}
/**
* Check if a person can teleport to the region (assuming he is not teleporting to a sign).
* @param person The person to check
* @param region The region to check for
* @return true if the person can teleport to it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(!(person instanceof 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")
|| region.getFriendsFeature().getFriends().contains(player.getUniqueId()) && player.hasPermission("areashop.teleportfriend");
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportavailable") && !sender.hasPermission("areashop.teleportavailablesign") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
messageBridge.message(sender, "teleport-noPermission");
return;
}
if(!(sender instanceof Player)) {
messageBridge.message(sender, "cmd-onlyByPlayer");
return;
}
if(args.length <= 1 || args[1] == null) {
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]);
return;
}
boolean toSign = args.length >= 3 && (
args[2].equalsIgnoreCase("sign")
|| args[2].equalsIgnoreCase("yes")
|| args[2].equalsIgnoreCase("true")
);
region.getTeleportFeature().teleportPlayer(player, toSign);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(fileManager.getRegionNames());
} else if(toComplete == 3) {
result.add("sign");
}
return result;
}
}
@@ -0,0 +1,112 @@
package me.wiefferink.areashop.commands;
import me.wiefferink.areashop.MessageBridge;
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;
@Singleton
public class UnrentCommand extends CommandAreaShop {
@Inject
private MessageBridge messageBridge;
@Inject
private IFileManager fileManager;
@Override
public String getCommandStart() {
return "areashop unrent";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.unrent") || target.hasPermission("areashop.unrentown")) {
return "help-unrent";
}
return null;
}
/**
* Check if a person can unrent the region.
* @param person The person to check
* @param region The region to check for
* @return true if the person can unrent it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(person.hasPermission("areashop.unrent")) {
return true;
}
if(person instanceof Player) {
Player player = (Player)person;
return region.isOwner(player) && person.hasPermission("areashop.unrentown");
}
return false;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
messageBridge.message(sender, "unrent-noPermission");
return;
}
RentRegion rent;
if(args.length <= 1) {
if(sender instanceof Player) {
// get the region by location
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
rent = regions.get(0);
}
} else {
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
rent = fileManager.getRent(args[1]);
}
if(rent == null) {
messageBridge.message(sender, "unrent-notRegistered");
return;
}
if(!rent.isRented()) {
messageBridge.message(sender, "unrent-notRented", rent);
return;
}
rent.unRent(true, sender);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(RentRegion region : fileManager.getRentsRef()) {
if(region.isRented()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,45 @@
package me.wiefferink.areashop.events;
public class CancellableRegionEvent<T> extends RegionEvent<T> {
private boolean cancelled;
private String reason;
public CancellableRegionEvent(T region) {
super(region);
}
/**
* Cancel the event from happening.
* @param reason The reason of cancelling, used for display to the user, should end with a dot
*/
public void cancel(String reason) {
this.cancelled = true;
this.reason = reason;
}
/**
* Let the event continue, possible overwriting a cancel() call from another plugin.
*/
public void allow() {
this.cancelled = false;
this.reason = null;
}
/**
* Check if the event has been cancelled.
* @return true if the event has been cancelled, otherwise false
*/
public boolean isCancelled() {
return cancelled;
}
/**
* Get the reason why this event is cancelled.
* @return null if there is no reason or the event is not cancelled, otherwise a string
*/
public String getReason() {
return reason;
}
}
@@ -0,0 +1,7 @@
package me.wiefferink.areashop.events;
public class NotifyRegionEvent<T> extends RegionEvent<T> {
public NotifyRegionEvent(T region) {
super(region);
}
}
@@ -0,0 +1,7 @@
# Events
This package contains event classes that allow other plugins to listen to events about AreaShop regions.
* `RegionEvent` class represents a generic event.
* `CancellableRegionEvent` represents an event that has a region and can be cancelled.
* `NotifyRegionEvent` represents events that are to inform only, and cannot be cancelled anymore (an `CancellableRegionEvent` would be sent first).
@@ -0,0 +1,31 @@
package me.wiefferink.areashop.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class RegionEvent<T> extends Event {
protected T region;
private static final HandlerList handlers = new HandlerList();
public RegionEvent(T region) {
this.region = region;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
// Required by Bukkit/Spigot
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the region of this event.
* @return The region the event is about
*/
public T getRegion() {
return region;
}
}
@@ -0,0 +1,19 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.GeneralRegion;
/**
* Broadcasted when a region has been added to AreaShop.
*/
public class AddingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
/**
* Constructor.
* @param region The region that has been added
*/
public AddingRegionEvent(GeneralRegion region) {
super(region);
}
}
@@ -0,0 +1,31 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.BuyRegion;
import org.bukkit.OfflinePlayer;
/**
* Broadcasted when a player tries to buy a region.
*/
public class BuyingRegionEvent extends CancellableRegionEvent<BuyRegion> {
private final OfflinePlayer player;
/**
* Constructor.
* @param region The region that is about to get bought
* @param player The player that tries to buy the region
*/
public BuyingRegionEvent(BuyRegion region, OfflinePlayer player) {
super(region);
this.player = player;
}
/**
* Get the player that is trying to buy the region.
* @return The player that is trying to buy the region
*/
public OfflinePlayer getPlayer() {
return player;
}
}
@@ -0,0 +1,19 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.GeneralRegion;
/**
* Broadcasted when a region has been added to AreaShop.
*/
public class DeletingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
/**
* Constructor.
* @param region The region that has been added
*/
public DeletingRegionEvent(GeneralRegion region) {
super(region);
}
}
@@ -0,0 +1,42 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.RentRegion;
import org.bukkit.OfflinePlayer;
/**
* Broadcasted when a player tries to rent a region.
*/
public class RentingRegionEvent extends CancellableRegionEvent<RentRegion> {
private final OfflinePlayer player;
private final boolean extending;
/**
* Constructor.
* @param region The region that is about to be rented
* @param player The player that tries to rent the region
* @param extending true if the player is extending the rental of the region, otherwise false
*/
public RentingRegionEvent(RentRegion region, OfflinePlayer player, boolean extending) {
super(region);
this.player = player;
this.extending = extending;
}
/**
* Get the player that is trying to rent the region.
* @return The player that is trying to rent the region
*/
public OfflinePlayer getPlayer() {
return player;
}
/**
* Check if the player is extending the region or renting it for the first time.
* @return true if the player tries to extend the region, false if he tries to rent it the first time
*/
public boolean isExtending() {
return extending;
}
}
@@ -0,0 +1,31 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.BuyRegion;
import org.bukkit.OfflinePlayer;
/**
* Broadcasted when a player tries to resell a region.
*/
public class ResellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
private final OfflinePlayer player;
/**
* Contructor.
* @param region The region that the player is trying to resell
* @param player The player that is trying to buy this region from the current owner
*/
public ResellingRegionEvent(BuyRegion region, OfflinePlayer player) {
super(region);
this.player = player;
}
/**
* Get the player that is trying to buy the region.
* @return The player that is trying to buy the region
*/
public OfflinePlayer getBuyer() {
return player;
}
}
@@ -0,0 +1,18 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.BuyRegion;
/**
* Broadcasted when a region is about to get sold.
*/
public class SellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
/**
* Constructor.
* @param region The region that is about to get sold
*/
public SellingRegionEvent(BuyRegion region) {
super(region);
}
}
@@ -0,0 +1,18 @@
package me.wiefferink.areashop.events.ask;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.RentRegion;
/**
* Broadcasted when a region is about to be unrented.
*/
public class UnrentingRegionEvent extends CancellableRegionEvent<RentRegion> {
/**
* Constructor.
* @param region The region that is about to be unrented
*/
public UnrentingRegionEvent(RentRegion region) {
super(region);
}
}
@@ -0,0 +1,43 @@
package me.wiefferink.areashop.events.askandnotify;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
/**
* Broadcasted when a friend is being added to a region.
*/
public class AddedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
private final OfflinePlayer friend;
private final CommandSender by;
/**
* Constructor.
* @param region The region the friend is getting added to
* @param friend The friend that is about to be added
* @param by The CommandSender that is adding the friend, or null if none
*/
public AddedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
super(region);
this.friend = friend;
this.by = by;
}
/**
* Get the OfflinePlayer that is getting added as friend.
* @return The friend that is getting added
*/
public OfflinePlayer getFriend() {
return friend;
}
/**
* Get the CommandSender that is adding the friend.
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
*/
public CommandSender getBy() {
return by;
}
}
@@ -0,0 +1,43 @@
package me.wiefferink.areashop.events.askandnotify;
import me.wiefferink.areashop.events.CancellableRegionEvent;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
/**
* Broadcasted when a friend is being added to a region.
*/
public class DeletedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
private final OfflinePlayer friend;
private final CommandSender by;
/**
* Constructor.
* @param region The region the friend is getting added to
* @param friend The friend that is about to be added
* @param by The CommandSender that is adding the friend, or null if none
*/
public DeletedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
super(region);
this.friend = friend;
this.by = by;
}
/**
* Get the OfflinePlayer that is getting added as friend.
* @return The friend that is getting added
*/
public OfflinePlayer getFriend() {
return friend;
}
/**
* Get the CommandSender that is adding the friend.
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
*/
public CommandSender getBy() {
return by;
}
}
Loaded 100 of 247 files, more files were not shown because too many files have changed in this diff. Show more