Compare commits

...
231 Commits
Author SHA1 Message Date
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
163 changed files with 16049 additions and 6624 deletions

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
# Maven stuff
/target
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
# IntelliJ IDEA
*.iml
+1 -2
View File
@@ -1,2 +1 @@
/.project
/.classpath
/target
-1
View File
@@ -1 +0,0 @@
/org.eclipse.jdt.core.prefs
-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
+156
View File
@@ -0,0 +1,156 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop</artifactId>
<packaging>jar</packaging>
<name>AreaShop</name>
<version>2.2.2</version> <!-- Main plugin version -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url>
</repository>
<repository>
<id>sk89q-repo-wg</id>
<url>http://maven.sk89q.com/artifactory/repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.7.9-R0.2</version>
<type>jar</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop-worldguard-5</artifactId>
<version>WorldGuard-5</version>
<type>jar</type>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop-worldguard-6</artifactId>
<version>WorldGuard-6</version>
<type>jar</type>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop-interface</artifactId>
<version>AreaShopInterface</version>
<type>jar</type>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop-worldedit-5</artifactId>
<version>WorldEdit-5</version>
<type>jar</type>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>nl.evolutioncoding</groupId>
<artifactId>areashop-worldedit-6</artifactId>
<version>WorldEdit-6</version>
<type>jar</type>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<version>6.0.0-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<version>6.0.0-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>net.milkbowl</groupId>
<artifactId>vault</artifactId>
<version>1.4.1</version>
<scope>system</scope>
<systemPath>${basedir}/../dependencies/Vault.jar</systemPath>
</dependency>
</dependencies>
<build>
<directory>target</directory>
<finalName>AreaShop</finalName>
<!-- Include all required resources -->
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>plugin.yml</include>
<include>config.yml</include>
<include>default.yml</include>
<include>README.md</include>
<include>lang/*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- Copy resulting file to local server, change to your own path -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<tasks>
<copy file="./target/${project.build.finalName}.jar" tofile="C:\Games\Minecraft\Spigot\plugins\${project.build.finalName}.jar"/>
</tasks>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,670 @@
package nl.evolutioncoding.areashop;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import net.milkbowl.vault.economy.Economy;
import nl.evolutioncoding.areashop.Updater.UpdateResult;
import nl.evolutioncoding.areashop.Updater.UpdateType;
import nl.evolutioncoding.areashop.features.DebugFeature;
import nl.evolutioncoding.areashop.features.Feature;
import nl.evolutioncoding.areashop.features.SignDisplayFeature;
import nl.evolutioncoding.areashop.features.WorldGuardRegionFlagsFeature;
import nl.evolutioncoding.areashop.interfaces.AreaShopInterface;
import nl.evolutioncoding.areashop.interfaces.WorldEditInterface;
import nl.evolutioncoding.areashop.interfaces.WorldGuardInterface;
import nl.evolutioncoding.areashop.listeners.PlayerLoginLogoutListener;
import nl.evolutioncoding.areashop.listeners.SignBreakListener;
import nl.evolutioncoding.areashop.listeners.SignChangeListener;
import nl.evolutioncoding.areashop.listeners.SignClickListener;
import nl.evolutioncoding.areashop.managers.CommandManager;
import nl.evolutioncoding.areashop.managers.FileManager;
import nl.evolutioncoding.areashop.managers.LanguageManager;
import nl.evolutioncoding.areashop.managers.SignLinkerManager;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
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.Listener;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
/**
* Main class for the AreaShop plugin
* @author NLThijs48
*/
public final class AreaShop extends JavaPlugin implements AreaShopInterface {
// General variables
private static AreaShop instance = null;
private WorldGuardPlugin worldGuard = null;
private WorldGuardInterface worldGuardInterface = null;
private WorldEditPlugin worldEdit = null;
private WorldEditInterface worldEditInterface = null;
private FileManager fileManager = null;
private LanguageManager languageManager = null;
private CommandManager commandManager = null;
private SignLinkerManager signLinkerManager = null;
private boolean debug = false;
private String chatprefix = null;
private Updater updater = null;
private boolean updateAvailable = false;
private boolean ready = false;
// Folders and file names
public static final String languageFolder = "lang";
public static final String schematicFolder = "schem";
public static final String schematicExtension = ".schematic";
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 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 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 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 AreaShop getInstance() {
return AreaShop.instance;
}
/**
* Called on start or reload of the server
*/
public void onEnable() {
AreaShop.instance = this;
boolean error = false;
// Check if WorldGuard is present
String wgVersion = null;
Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard");
if (plugin == null || !(plugin instanceof WorldGuardPlugin)) {
this.getLogger().severe("WorldGuard plugin is not present or has not loaded correctly");
error = true;
} else {
worldGuard = (WorldGuardPlugin)plugin;
// Get correct WorldGuardInterface (handles things that changed version to version)
if(worldGuard.getDescription().getVersion().startsWith("5.")) {
wgVersion = "5";
} else {
wgVersion = "6";
}
try {
final Class<?> clazz = Class.forName("nl.evolutioncoding.areashop.handlers.WorldGuardHandler" + wgVersion);
// Check if we have a NMSHandler class at that location.
if (WorldGuardInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldGuardInterface
this.worldGuardInterface = (WorldGuardInterface) clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
}
} catch (final Exception e) {
e.printStackTrace();
this.getLogger().severe("Could not load the handler for WorldGuard (tried to load " + wgVersion + "), report this problem to the author.");
error = true;
wgVersion = null;
}
}
// Check if WorldEdit is present
String weVersion = null;
plugin = getServer().getPluginManager().getPlugin("WorldEdit");
if (plugin == null || !(plugin instanceof WorldEditPlugin)) {
this.getLogger().severe("WorldEdit plugin is not present or has not loaded correctly");
error = true;
} else {
worldEdit = (WorldEditPlugin)plugin;
// Get correct WorldEditInterface (handles things that changed version to version)
if(worldEdit.getDescription().getVersion().startsWith("5.")) {
weVersion = "5";
} else {
weVersion = "6";
}
try {
final Class<?> clazz = Class.forName("nl.evolutioncoding.areashop.handlers.WorldEditHandler" + weVersion);
// Check if we have a NMSHandler class at that location.
if (WorldEditInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldEditInterface
this.worldEditInterface = (WorldEditInterface) clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
}
} catch (final Exception e) {
e.printStackTrace();
this.getLogger().severe("Could not load the handler for WorldEdit (tried to load " + weVersion + "), report this problem to the author.");
error = true;
weVersion = null;
}
}
// Check if Vault is present
if(getServer().getPluginManager().getPlugin("Vault") == null) {
this.getLogger().severe("Vault plugin is not present or has not loaded correctly");
error = true;
}
// Load all data from files and check versions
fileManager = new FileManager(this);
error = error | !fileManager.loadFiles();
// Print loaded version of WG and WE in debug
if(wgVersion != null) {
AreaShop.debug("Loaded WorldGuardHandler" + wgVersion);
}
if(weVersion != null) {
AreaShop.debug("Loaded WorldEditHandler" + weVersion);
}
// Create a LanguageMananager
languageManager = new LanguageManager(this);
if(error) {
this.getLogger().severe("The plugin has not started, fix the errors listed above");
} else {
// Register the event listeners
this.getServer().getPluginManager().registerEvents(new SignChangeListener(this), this);
this.getServer().getPluginManager().registerEvents(new SignBreakListener(this), this);
this.getServer().getPluginManager().registerEvents(new SignClickListener(this), this);
this.getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this), this);
setupFeatures();
setupTasks();
// Startup the CommandManager (registers itself for the command)
commandManager = new CommandManager(this);
// Create a signLinkerManager
signLinkerManager = new SignLinkerManager(this);
// Enable Metrics if config allows it
if(this.getConfig().getBoolean("sendStats")) {
this.startMetrics();
}
// Register dynamic permission (things declared in config)
registerDynamicPermissions();
// Dont initialize the updatechecker if disabled in the config
if(this.getConfig().getBoolean("checkForUpdates")) {
new BukkitRunnable() {
@Override
public void run() {
try {
updater = new Updater(AreaShop.getInstance(), 76518, null, UpdateType.NO_DOWNLOAD, false);
AreaShop.debug("Result=" + updater.getResult().toString() + ", Latest=" + updater.getLatestName() + ", Type=" + updater.getLatestType());
updateAvailable = updater.getResult() == UpdateResult.UPDATE_AVAILABLE;
if(updateAvailable) {
AreaShop.getInstance().getLogger().info("Update from AreaShop V" + AreaShop.getInstance().getDescription().getVersion() + " to " + updater.getLatestName() + " available, get the latest version at http://dev.bukkit.org/bukkit-plugins/regionbuyandrent/");
new BukkitRunnable() {
@Override
public void run() {
for(Player player : Utils.getOnlinePlayers()) {
if(player.hasPermission("areashop.notifyupdate")) {
AreaShop.getInstance().message(player, "update-playerNotify", AreaShop.getInstance().getDescription().getVersion(), AreaShop.getInstance().getUpdater().getLatestName());
}
}
}
}.runTask(AreaShop.getInstance());
}
} catch(Exception e) {
AreaShop.debug("Something went wrong with the Updater:");
AreaShop.debug(e.getMessage());
updateAvailable = false;
}
}
}.runTaskAsynchronously(this);
}
}
}
/**
* Called on shutdown or reload of the server
*/
public void onDisable() {
// Update lastactive time for players that are online now
for(GeneralRegion region : fileManager.getRegions()) {
Player player = Bukkit.getPlayer(region.getOwner());
if(player != null) {
region.updateLastActiveTime();
}
}
fileManager.saveRequiredFilesAtOnce();
Bukkit.getServer().getScheduler().cancelTasks(this);
worldGuard = null;
worldEdit = null;
fileManager = null;
languageManager = null;
commandManager = null;
chatprefix = null;
debug = false;
ready = false;
updater = null;
}
/**
* Instanciate and register all Feature classes
*/
public void setupFeatures() {
Set<Feature> features = new HashSet<>();
features.add(new DebugFeature(this));
features.add(new SignDisplayFeature(this));
features.add(new WorldGuardRegionFlagsFeature(this));
// Register as listener when necessary
for(Feature feature : features) {
if(feature instanceof Listener) {
this.getServer().getPluginManager().registerEvents((Listener)feature, 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;
}
/**
* 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 like &1)
*/
public void setChatprefix(String chatprefix) {
this.chatprefix = chatprefix;
}
/**
* Function to get the WorldGuard plugin
* @return WorldGuardPlugin
*/
public WorldGuardPlugin getWorldGuard() {
return worldGuard;
}
/**
* Function to get WorldGuardInterface for version dependent things
* @return WorldGuardInterface
*/
public WorldGuardInterface getWorldGuardHandler() {
return this.worldGuardInterface;
}
/**
* Function to get the WorldEdit plugin
* @return WorldEditPlugin
*/
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;
}
/**
* Function to get the CommandManager
* @return the CommandManager
*/
public CommandManager getCommandManager() {
return commandManager;
}
public SignLinkerManager getSignlinkerManager() {
return signLinkerManager;
}
/**
* Function to get the Vault plugin
* @return Economy
*/
public Economy getEconomy() {
RegisteredServiceProvider<Economy> economy = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economy == null || economy.getProvider() == null) {
this.getLogger().severe("There is no economy provider to support Vault, make sure you installed an economy plugin");
return null;
}
return economy.getProvider();
}
/**
* Get the current chatPrefix
* @return The current chatPrefix
*/
public String getChatPrefix() {
return chatprefix;
}
/**
* Method to get the FileManager (loads/save regions and can be used to get regions)
* @return The fileManager
*/
public FileManager getFileManager() {
return fileManager;
}
/**
* Get the updater (check the update result)
* @return The updater
*/
public Updater getUpdater() {
return updater;
}
/**
* Check if an update for AreaShop is available
* @return true if an update is available, otherwise false
*/
public boolean updateAvailable() {
return updateAvailable;
}
/**
* Register dynamic permissions controlled by config settings
*/
public 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) {
this.getLogger().warning("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
*/
public void setupTasks() {
// Rent expiration timer
long expirationCheck = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("expiration.delay"));
final AreaShop finalPlugin = this;
if(expirationCheck > 0) {
new BukkitRunnable() {
@Override
public void run() {
if(isReady()) {
finalPlugin.getFileManager().checkRents();
AreaShop.debugTask("Checking rent expirations...");
} else {
AreaShop.debugTask("Skipped checking rent expirations, plugin not ready");
}
}
}.runTaskTimer(this, 1, expirationCheck);
}
// Inactive unrenting/selling timer
long inactiveCheck = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("inactive.delay"));
if(inactiveCheck > 0) {
new BukkitRunnable() {
@Override
public void run() {
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");
}
}
}.runTaskTimer(this, inactiveCheck, inactiveCheck);
}
// Periodic updating of signs for timeleft tags
long periodicUpdate = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("signs.delay"));
if(periodicUpdate > 0) {
new BukkitRunnable() {
@Override
public void run() {
if(isReady()) {
finalPlugin.getFileManager().performPeriodicSignUpdate();
AreaShop.debugTask("Performing periodic sign update...");
} else {
AreaShop.debugTask("Skipped performing periodic sign update, plugin not ready");
}
}
}.runTaskTimer(this, periodicUpdate, periodicUpdate);
}
// Saving regions and group settings
long saveFiles = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("saving.delay"));
if(saveFiles > 0) {
new BukkitRunnable() {
@Override
public void run() {
if(isReady()) {
finalPlugin.getFileManager().saveRequiredFiles();
AreaShop.debugTask("Saving required files...");
} else {
AreaShop.debugTask("Skipped saving required files, plugin not ready");
}
}
}.runTaskTimer(this, saveFiles, saveFiles);
}
// Sending warnings about rent regions to online players
long expireWarning = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("expireWarning.delay"));
if(expireWarning > 0) {
new BukkitRunnable() {
@Override
public void run() {
if(isReady()) {
finalPlugin.getFileManager().sendRentExpireWarnings();
AreaShop.debugTask("Sending rent expire warnings...");
} else {
AreaShop.debugTask("Skipped sending rent expire warnings, plugin not ready");
}
}
}.runTaskTimer(this, expireWarning, expireWarning);
}
// Update all regions on startup
if(getConfig().getBoolean("updateRegionsOnStartup")) {
new BukkitRunnable() {
@Override
public void run() {
finalPlugin.getFileManager().updateAllRegions();
AreaShop.debugTask("Updating all regions at startup...");
}
}.runTaskLater(this, 20L);
}
}
/**
* Method to send a message to a CommandSender, using chatprefix if it is a player
* @param target The CommandSender you wan't to send the message to (e.g. a player)
* @param key The key to get the translation
* @param prefix Specify if the message should have a prefix
* @param params The parameters to inject into the message string
*/
public void configurableMessage(Object target, String key, boolean prefix, Object... params) {
if(target == null) {
return;
}
String langString = Utils.applyColors(languageManager.getLang(key, params));
if(langString == null || langString.equals("")) {
// Do nothing, message is not available or disabled
} else {
if(target instanceof Player) {
if(prefix) {
((Player)target).sendMessage(Utils.applyColors(chatprefix)+langString);
} else {
((Player)target).sendMessage(langString);
}
} else if(target instanceof CommandSender) {
if(!getConfig().getBoolean("useColorsInConsole")) {
langString = ChatColor.stripColor(langString);
}
((CommandSender)target).sendMessage(langString);
}
else if(target instanceof Logger) {
if(!getConfig().getBoolean("useColorsInConsole")) {
langString = ChatColor.stripColor(langString);
}
((Logger)target).info(langString);
} else {
langString = ChatColor.stripColor(langString);
this.getLogger().info("Could not send message, target is wrong: " + langString);
}
}
}
public void messageNoPrefix(Object target, String key, Object... params) {
configurableMessage(target, key, false, params);
}
public void message(Object target, String key, Object... params) {
configurableMessage(target, key, true, params);
}
/**
* Return the config
*/
@Override
public YamlConfiguration getConfig() {
return fileManager.getConfig();
}
/**
* Start the Metrics stats collection
*/
private void startMetrics() {
try {
Metrics metrics = new Metrics(this);
metrics.start();
} catch (Exception e) {
AreaShop.debug("Could not start Metrics");
}
}
/**
* Sends an debug message to the console
* @param message The message that should be printed to the console
*/
public static void debug(String message) {
if(AreaShop.getInstance().debug) {
AreaShop.getInstance().getLogger().info("Debug: " + message);
}
}
/**
* Non-static debug to use as implementation of the interface
*/
public void debugI(String message) {
AreaShop.debug(message);
}
/**
* Print debug message for periodic task
* @param message The message to print
*/
public static void debugTask(String message) {
if(AreaShop.getInstance().getConfig().getBoolean("debugTask")) {
AreaShop.debug(message);
}
}
/**
* Reload all files of the plugin and update all regions
* confirmationReceiver The CommandSender that should receive confirmation messages, null for nobody
*/
public void reload(final CommandSender confirmationReceiver) {
setReady(false);
fileManager.saveRequiredFilesAtOnce();
fileManager.loadFiles();
languageManager.startup();
message(confirmationReceiver, "reload-reloading");
fileManager.checkRents();
fileManager.updateAllRegions(confirmationReceiver);
}
/**
* Reload all files of the plugin and update all regions
*/
public void reload() {
reload(null);
}
}
@@ -25,32 +25,24 @@
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package nl.evolutioncoding.AreaShop;
package nl.evolutioncoding.areashop;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.lang.reflect.Method;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
@@ -117,7 +109,7 @@ public class Metrics {
private volatile BukkitTask task = null;
public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) {
if(plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
@@ -133,7 +125,7 @@ public class Metrics {
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
if(configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org").copyDefaults(true);
configuration.save(configurationFile);
}
@@ -146,12 +138,11 @@ public class Metrics {
/**
* Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics
* website. Plotters can be added to the graph object returned.
*
* @param name The name of the graph
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
*/
public Graph createGraph(final String name) {
if (name == null) {
if(name == null) {
throw new IllegalArgumentException("Graph name cannot be null");
}
@@ -167,11 +158,10 @@ public class Metrics {
/**
* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
*
* @param graph The name of the graph
*/
public void addGraph(final Graph graph) {
if (graph == null) {
if(graph == null) {
throw new IllegalArgumentException("Graph cannot be null");
}
@@ -182,18 +172,17 @@ public class Metrics {
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
* ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
synchronized(optOutLock) {
// Did we opt out?
if (isOptOut()) {
if(isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
if(task != null) {
return true;
}
@@ -205,13 +194,13 @@ public class Metrics {
public void run() {
try {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
synchronized(optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && task != null) {
if(isOptOut() && task != null) {
task.cancel();
task = null;
// Tell all plotters to stop gathering information.
for (Graph graph : graphs) {
for(Graph graph : graphs) {
graph.onOptOut();
}
}
@@ -225,8 +214,8 @@ public class Metrics {
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
} catch(IOException e) {
if(debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
@@ -239,21 +228,20 @@ public class Metrics {
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
synchronized(optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
} catch(IOException ex) {
if(debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
} catch(InvalidConfigurationException ex) {
if(debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
@@ -264,20 +252,18 @@ public class Metrics {
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
synchronized(optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
if(isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
if(task == null) {
start();
}
}
@@ -285,20 +271,18 @@ public class Metrics {
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
synchronized(optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (!isOptOut()) {
if(!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
if(task != null) {
task.cancel();
task = null;
}
@@ -307,7 +291,6 @@ public class Metrics {
/**
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
@@ -322,6 +305,27 @@ public class Metrics {
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Gets the online player (backwards compatibility)
* @return online player amount
*/
private int getOnlinePlayers() {
try {
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
if(onlinePlayerMethod.getReturnType().equals(Collection.class)) {
return ((Collection<?>)onlinePlayerMethod.invoke(Bukkit.getServer())).size();
} else {
return ((Player[])onlinePlayerMethod.invoke(Bukkit.getServer())).length;
}
} catch(Exception ex) {
if(debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
}
return 0;
}
/**
* Generic method that posts a plugin to the metrics website
*/
@@ -332,7 +336,7 @@ public class Metrics {
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().length;
int playersOnline = this.getOnlinePlayers();
// END server software specific section -- all code below does not use any code outside of this class / Java
@@ -354,7 +358,7 @@ public class Metrics {
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
if(osarch.equals("amd64")) {
osarch = "x86_64";
}
@@ -366,12 +370,12 @@ public class Metrics {
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
if(isPing) {
appendJSONPair(json, "ping", "1");
}
if (graphs.size() > 0) {
synchronized (graphs) {
if(graphs.size() > 0) {
synchronized(graphs) {
json.append(',');
json.append('"');
json.append("graphs");
@@ -383,19 +387,19 @@ public class Metrics {
final Iterator<Graph> iter = graphs.iterator();
while (iter.hasNext()) {
while(iter.hasNext()) {
Graph graph = iter.next();
StringBuilder graphJson = new StringBuilder();
graphJson.append('{');
for (Plotter plotter : graph.getPlotters()) {
for(Plotter plotter : graph.getPlotters()) {
appendJSONPair(graphJson, plotter.getColumnName(), Integer.toString(plotter.getValue()));
}
graphJson.append('}');
if (!firstGraph) {
if(!firstGraph) {
json.append(',');
}
@@ -421,7 +425,7 @@ public class Metrics {
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
if(isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
@@ -441,7 +445,7 @@ public class Metrics {
connection.setDoOutput(true);
if (debug) {
if(debug) {
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
@@ -458,24 +462,24 @@ public class Metrics {
os.close();
reader.close();
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
if(response == null || response.startsWith("ERR") || response.startsWith("7")) {
if(response == null) {
response = "null";
} else if (response.startsWith("7")) {
} else if(response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
} else {
// Is this the first update this hour?
if (response.equals("1") || response.contains("This is your first update this hour")) {
synchronized (graphs) {
if(response.equals("1") || response.contains("This is your first update this hour")) {
synchronized(graphs) {
final Iterator<Graph> iter = graphs.iterator();
while (iter.hasNext()) {
while(iter.hasNext()) {
final Graph graph = iter.next();
for (Plotter plotter : graph.getPlotters()) {
for(Plotter plotter : graph.getPlotters()) {
plotter.reset();
}
}
@@ -486,9 +490,6 @@ public class Metrics {
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -497,12 +498,12 @@ public class Metrics {
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
} catch(IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) try {
if(gzos != null) try {
gzos.close();
} catch (IOException ignore) {
} catch(IOException ignore) {
}
}
@@ -511,46 +512,40 @@ public class Metrics {
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
} catch(Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
if(value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
} catch(NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
if(json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
if(isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
@@ -559,18 +554,15 @@ public class Metrics {
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
for(int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
switch(chr) {
case '"':
case '\\':
builder.append('\\');
@@ -589,7 +581,7 @@ public class Metrics {
builder.append("\\r");
break;
default:
if (chr < ' ') {
if(chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
@@ -605,7 +597,6 @@ public class Metrics {
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
@@ -635,7 +626,6 @@ public class Metrics {
/**
* Gets the graph's name
*
* @return the Graph's name
*/
public String getName() {
@@ -644,7 +634,6 @@ public class Metrics {
/**
* Add a plotter to the graph, which will be used to plot entries
*
* @param plotter the plotter to add to the graph
*/
public void addPlotter(final Plotter plotter) {
@@ -653,7 +642,6 @@ public class Metrics {
/**
* Remove a plotter from the graph
*
* @param plotter the plotter to remove from the graph
*/
public void removePlotter(final Plotter plotter) {
@@ -662,7 +650,6 @@ public class Metrics {
/**
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
*
* @return an unmodifiable {@link java.util.Set} of the plotter objects
*/
public Set<Plotter> getPlotters() {
@@ -676,11 +663,11 @@ public class Metrics {
@Override
public boolean equals(final Object object) {
if (!(object instanceof Graph)) {
if(!(object instanceof Graph)) {
return false;
}
final Graph graph = (Graph) object;
final Graph graph = (Graph)object;
return graph.name.equals(name);
}
@@ -710,7 +697,6 @@ public class Metrics {
/**
* Construct a plotter with a specific plot name
*
* @param name the name of the plotter to use, which will show up on the website
*/
public Plotter(final String name) {
@@ -721,14 +707,12 @@ public class Metrics {
* Get the current value for the plotted point. Since this function defers to an external function it may or may
* not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called
* from any thread so care should be taken when accessing resources that need to be synchronized.
*
* @return the current value for the point to be plotted.
*/
public abstract int getValue();
/**
* Get the column name for the plotted point
*
* @return the plotted point's column name
*/
public String getColumnName() {
@@ -748,11 +732,11 @@ public class Metrics {
@Override
public boolean equals(final Object object) {
if (!(object instanceof Plotter)) {
if(!(object instanceof Plotter)) {
return false;
}
final Plotter plotter = (Plotter) object;
final Plotter plotter = (Plotter)object;
return plotter.name.equals(name) && plotter.getValue() == getValue();
}
}
@@ -0,0 +1,746 @@
package nl.evolutioncoding.areashop;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
* Check for updates on BukkitDev for a given plugin, and download the updates if needed.
* <p/>
* <b>VERY, VERY IMPORTANT</b>: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
* <br>
* It is a <b>BUKKIT POLICY</b> that you include a boolean value in your config that prevents the auto-updater from running <b>AT ALL</b>.
* <br>
* If you fail to include this option in your config, your plugin will be <b>REJECTED</b> when you attempt to submit it to dev.bukkit.org.
* <p/>
* An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
* <br>
* If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
*
* @author Gravity
* @version 2.3
*/
public class Updater {
/* Constants */
// Remote file's title
private static final String TITLE_VALUE = "name";
// Remote file's download link
private static final String LINK_VALUE = "downloadUrl";
// Remote file's release type
private static final String TYPE_VALUE = "releaseType";
// Remote file's build version
private static final String VERSION_VALUE = "gameVersion";
// Path to GET
private static final String QUERY = "/servermods/files?projectIds=";
// Slugs will be appended to this to get to the project's RSS feed
private static final String HOST = "https://api.curseforge.com";
// User-agent when querying Curse
private static final String USER_AGENT = "Updater (by Gravity)";
// Used for locating version numbers in file names
private static final String DELIMETER = "^V|[\\s_-]V";
// If the version number contains one of these, don't update.
private static final String[] NO_UPDATE_TAG = { "-DEV", "-PRE", "-SNAPSHOT" };
// Used for downloading files
private static final int BYTE_SIZE = 1024;
// Config key for api key
private static final String API_KEY_CONFIG_KEY = "api-key";
// Config key for disabling Updater
private static final String DISABLE_CONFIG_KEY = "disable";
// Default api key value in config
private static final String API_KEY_DEFAULT = "PUT_API_KEY_HERE";
// Default disable value in config
private static final boolean DISABLE_DEFAULT = false;
/* User-provided variables */
// Plugin running Updater
private final Plugin plugin;
// Type of update check to run
private final UpdateType type;
// Whether to announce file downloads
private final boolean announce;
// The plugin file (jar)
private final File file;
// The folder that downloads will be placed in
private final File updateFolder;
// The provided callback (if any)
private final UpdateCallback callback;
// Project's Curse ID
private int id = -1;
// BukkitDev ServerMods API key
private String apiKey = null;
/* Collected from Curse API */
private String versionName;
private String versionLink;
private String versionType;
private String versionGameVersion;
/* Update process variables */
// Connection to RSS
private URL url;
// Updater thread
private Thread thread;
// Used for determining the outcome of the update process
private Updater.UpdateResult result = Updater.UpdateResult.SUCCESS;
/**
* Gives the developer the result of the update process. Can be obtained by called {@link #getResult()}
*/
public enum UpdateResult {
/**
* The updater found an update, and has readied it to be loaded the next time the server restarts/reloads.
*/
SUCCESS,
/**
* The updater did not find an update, and nothing was downloaded.
*/
NO_UPDATE,
/**
* The server administrator has disabled the updating system.
*/
DISABLED,
/**
* The updater found an update, but was unable to download it.
*/
FAIL_DOWNLOAD,
/**
* For some reason, the updater was unable to contact dev.bukkit.org to download the file.
*/
FAIL_DBO,
/**
* When running the version check, the file on DBO did not contain a recognizable version.
*/
FAIL_NOVERSION,
/**
* The id provided by the plugin running the updater was invalid and doesn't exist on DBO.
*/
FAIL_BADID,
/**
* The server administrator has improperly configured their API key in the configuration.
*/
FAIL_APIKEY,
/**
* The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.
*/
UPDATE_AVAILABLE
}
/**
* Allows the developer to specify the type of update that will be run.
*/
public enum UpdateType {
/**
* Run a version check, and then if the file is out of date, download the newest version.
*/
DEFAULT,
/**
* Don't run a version check, just find the latest update and download it.
*/
NO_VERSION_CHECK,
/**
* Get information about the version and the download size, but don't actually download anything.
*/
NO_DOWNLOAD
}
/**
* Represents the various release types of a file on BukkitDev.
*/
public enum ReleaseType {
/**
* An "alpha" file.
*/
ALPHA,
/**
* A "beta" file.
*/
BETA,
/**
* A "release" file.
*/
RELEASE
}
/**
* Initialize the updater.
*
* @param plugin The plugin that is checking for an update.
* @param id The dev.bukkit.org id of the project.
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
* @param type Specify the type of update this will be. See {@link UpdateType}
* @param announce True if the program should announce the progress of new updates in console.
*/
public Updater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
this(plugin, id, file, type, null, announce);
}
/**
* Initialize the updater with the provided callback.
*
* @param plugin The plugin that is checking for an update.
* @param id The dev.bukkit.org id of the project.
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
* @param type Specify the type of update this will be. See {@link UpdateType}
* @param callback The callback instance to notify when the Updater has finished
*/
public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback) {
this(plugin, id, file, type, callback, false);
}
/**
* Initialize the updater with the provided callback.
*
* @param plugin The plugin that is checking for an update.
* @param id The dev.bukkit.org id of the project.
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
* @param type Specify the type of update this will be. See {@link UpdateType}
* @param callback The callback instance to notify when the Updater has finished
* @param announce True if the program should announce the progress of new updates in console.
*/
public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback, boolean announce) {
this.plugin = plugin;
this.type = type;
this.announce = announce;
this.file = file;
this.id = id;
this.updateFolder = this.plugin.getServer().getUpdateFolderFile();
this.callback = callback;
final File pluginFile = this.plugin.getDataFolder().getParentFile();
final File updaterFile = new File(pluginFile, "Updater");
final File updaterConfigFile = new File(updaterFile, "config.yml");
YamlConfiguration config = new YamlConfiguration();
config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n'
+ "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n'
+ "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration.");
config.addDefault(API_KEY_CONFIG_KEY, API_KEY_DEFAULT);
config.addDefault(DISABLE_CONFIG_KEY, DISABLE_DEFAULT);
if (!updaterFile.exists()) {
this.fileIOOrError(updaterFile, updaterFile.mkdir(), true);
}
boolean createFile = !updaterConfigFile.exists();
try {
if (createFile) {
this.fileIOOrError(updaterConfigFile, updaterConfigFile.createNewFile(), true);
config.options().copyDefaults(true);
config.save(updaterConfigFile);
} else {
config.load(updaterConfigFile);
}
} catch (final Exception e) {
final String message;
if (createFile) {
message = "The updater could not create configuration at " + updaterFile.getAbsolutePath();
} else {
message = "The updater could not load configuration at " + updaterFile.getAbsolutePath();
}
this.plugin.getLogger().log(Level.SEVERE, message, e);
}
if (config.getBoolean(DISABLE_CONFIG_KEY)) {
this.result = UpdateResult.DISABLED;
return;
}
String key = config.getString(API_KEY_CONFIG_KEY);
if (API_KEY_DEFAULT.equalsIgnoreCase(key) || "".equals(key)) {
key = null;
}
this.apiKey = key;
try {
this.url = new URL(Updater.HOST + Updater.QUERY + this.id);
} catch (final MalformedURLException e) {
this.plugin.getLogger().log(Level.SEVERE, "The project ID provided for updating, " + this.id + " is invalid.", e);
this.result = UpdateResult.FAIL_BADID;
}
if (this.result != UpdateResult.FAIL_BADID) {
this.thread = new Thread(new UpdateRunnable());
this.thread.start();
} else {
runUpdater();
}
}
/**
* Get the result of the update process.
*
* @return result of the update process.
* @see UpdateResult
*/
public Updater.UpdateResult getResult() {
this.waitForThread();
return this.result;
}
/**
* Get the latest version's release type.
*
* @return latest version's release type.
* @see ReleaseType
*/
public ReleaseType getLatestType() {
this.waitForThread();
if (this.versionType != null) {
for (ReleaseType type : ReleaseType.values()) {
if (this.versionType.equalsIgnoreCase(type.name())) {
return type;
}
}
}
return null;
}
/**
* Get the latest version's game version (such as "CB 1.2.5-R1.0").
*
* @return latest version's game version.
*/
public String getLatestGameVersion() {
this.waitForThread();
return this.versionGameVersion;
}
/**
* Get the latest version's name (such as "Project v1.0").
*
* @return latest version's name.
*/
public String getLatestName() {
this.waitForThread();
return this.versionName;
}
/**
* Get the latest version's direct file link.
*
* @return latest version's file link.
*/
public String getLatestFileLink() {
this.waitForThread();
return this.versionLink;
}
/**
* As the result of Updater output depends on the thread's completion, it is necessary to wait for the thread to finish
* before allowing anyone to check the result.
*/
private void waitForThread() {
if ((this.thread != null) && this.thread.isAlive()) {
try {
this.thread.join();
} catch (final InterruptedException e) {
this.plugin.getLogger().log(Level.SEVERE, null, e);
}
}
}
/**
* Save an update from dev.bukkit.org into the server's update folder.
*
* @param file the name of the file to save it as.
*/
private void saveFile(String file) {
final File folder = this.updateFolder;
deleteOldFiles();
if (!folder.exists()) {
this.fileIOOrError(folder, folder.mkdir(), true);
}
downloadFile();
// Check to see if it's a zip file, if it is, unzip it.
final File dFile = new File(folder.getAbsolutePath(), file);
if (dFile.getName().endsWith(".zip")) {
// Unzip
this.unzip(dFile.getAbsolutePath());
}
if (this.announce) {
this.plugin.getLogger().info("Finished updating.");
}
}
/**
* Download a file and save it to the specified folder.
*/
private void downloadFile() {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
URL fileUrl = new URL(this.versionLink);
final int fileLength = fileUrl.openConnection().getContentLength();
in = new BufferedInputStream(fileUrl.openStream());
fout = new FileOutputStream(new File(this.updateFolder, file.getName()));
final byte[] data = new byte[Updater.BYTE_SIZE];
int count;
if (this.announce) {
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
}
long downloaded = 0;
while ((count = in.read(data, 0, Updater.BYTE_SIZE)) != -1) {
downloaded += count;
fout.write(data, 0, count);
final int percent = (int) ((downloaded * 100) / fileLength);
if (this.announce && ((percent % 10) == 0)) {
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
}
}
} catch (Exception ex) {
this.plugin.getLogger().log(Level.WARNING, "The auto-updater tried to download a new update, but was unsuccessful.", ex);
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
} finally {
try {
if (in != null) {
in.close();
}
} catch (final IOException ex) {
this.plugin.getLogger().log(Level.SEVERE, null, ex);
}
try {
if (fout != null) {
fout.close();
}
} catch (final IOException ex) {
this.plugin.getLogger().log(Level.SEVERE, null, ex);
}
}
}
/**
* Remove possibly leftover files from the update folder.
*/
private void deleteOldFiles() {
//Just a quick check to make sure we didn't leave any files from last time...
File[] list = listFilesOrError(this.updateFolder);
for (final File xFile : list) {
if (xFile.getName().endsWith(".zip")) {
this.fileIOOrError(xFile, xFile.mkdir(), true);
}
}
}
/**
* Part of Zip-File-Extractor, modified by Gravity for use with Updater.
*
* @param file the location of the file to extract.
*/
private void unzip(String file) {
final File fSourceZip = new File(file);
try {
final String zipPath = file.substring(0, file.length() - 4);
ZipFile zipFile = new ZipFile(fSourceZip);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = e.nextElement();
File destinationFilePath = new File(zipPath, entry.getName());
this.fileIOOrError(destinationFilePath.getParentFile(), destinationFilePath.getParentFile().mkdirs(), true);
if (!entry.isDirectory()) {
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
int b;
final byte[] buffer = new byte[Updater.BYTE_SIZE];
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
final BufferedOutputStream bos = new BufferedOutputStream(fos, Updater.BYTE_SIZE);
while ((b = bis.read(buffer, 0, Updater.BYTE_SIZE)) != -1) {
bos.write(buffer, 0, b);
}
bos.flush();
bos.close();
bis.close();
final String name = destinationFilePath.getName();
if (name.endsWith(".jar") && this.pluginExists(name)) {
File output = new File(this.updateFolder, name);
this.fileIOOrError(output, destinationFilePath.renameTo(output), true);
}
}
}
zipFile.close();
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
moveNewZipFiles(zipPath);
} catch (final IOException e) {
this.plugin.getLogger().log(Level.SEVERE, "The auto-updater tried to unzip a new update file, but was unsuccessful.", e);
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
} finally {
this.fileIOOrError(fSourceZip, fSourceZip.delete(), false);
}
}
/**
* Find any new files extracted from an update into the plugin's data directory.
* @param zipPath path of extracted files.
*/
private void moveNewZipFiles(String zipPath) {
File[] list = listFilesOrError(new File(zipPath));
for (final File dFile : list) {
if (dFile.isDirectory() && this.pluginExists(dFile.getName())) {
// Current dir
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName());
// List of existing files in the new dir
final File[] dList = listFilesOrError(dFile);
// List of existing files in the current dir
final File[] oList = listFilesOrError(oFile);
for (File cFile : dList) {
// Loop through all the files in the new dir
boolean found = false;
for (final File xFile : oList) {
// Loop through all the contents in the current dir to see if it exists
if (xFile.getName().equals(cFile.getName())) {
found = true;
break;
}
}
if (!found) {
// Move the new file into the current dir
File output = new File(oFile, cFile.getName());
this.fileIOOrError(output, cFile.renameTo(output), true);
} else {
// This file already exists, so we don't need it anymore.
this.fileIOOrError(cFile, cFile.delete(), false);
}
}
}
this.fileIOOrError(dFile, dFile.delete(), false);
}
File zip = new File(zipPath);
this.fileIOOrError(zip, zip.delete(), false);
}
/**
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
*
* @param name a name to check for inside the plugins folder.
* @return true if a file inside the plugins folder is named this.
*/
private boolean pluginExists(String name) {
File[] plugins = listFilesOrError(new File("plugins"));
for (final File file : plugins) {
if (file.getName().equals(name)) {
return true;
}
}
return false;
}
/**
* Check to see if the program should continue by evaluating whether the plugin is already updated, or shouldn't be updated.
*
* @return true if the version was located and is not the same as the remote's newest.
*/
private boolean versionCheck() {
final String title = this.versionName;
if (this.type != UpdateType.NO_VERSION_CHECK) {
final String localVersion = this.plugin.getDescription().getVersion();
if (title.split(DELIMETER).length == 2) {
// Get the newest file's version number
final String remoteVersion = title.split(DELIMETER)[1].split(" ")[0];
if (this.hasTag(localVersion) || !this.shouldUpdate(localVersion, remoteVersion)) {
// We already have the latest version, or this build is tagged for no-update
this.result = Updater.UpdateResult.NO_UPDATE;
return false;
}
} else {
// The file's name did not contain the string 'vVersion'
final String authorInfo = this.plugin.getDescription().getAuthors().isEmpty() ? "" : " (" + this.plugin.getDescription().getAuthors().get(0) + ")";
this.plugin.getLogger().warning("The author of this plugin" + authorInfo + " has misconfigured their Auto Update system");
this.plugin.getLogger().warning("File versions should follow the format 'PluginName vVERSION'");
this.plugin.getLogger().warning("Please notify the author of this error.");
this.result = Updater.UpdateResult.FAIL_NOVERSION;
return false;
}
}
return true;
}
/**
* <b>If you wish to run mathematical versioning checks, edit this method.</b>
* <p>
* With default behavior, Updater will NOT verify that a remote version available on BukkitDev
* which is not this version is indeed an "update".
* If a version is present on BukkitDev that is not the version that is currently running,
* Updater will assume that it is a newer version.
* This is because there is no standard versioning scheme, and creating a calculation that can
* determine whether a new update is actually an update is sometimes extremely complicated.
* </p>
* <p>
* Updater will call this method from {@link #versionCheck()} before deciding whether
* the remote version is actually an update.
* If you have a specific versioning scheme with which a mathematical determination can
* be reliably made to decide whether one version is higher than another, you may
* revise this method, using the local and remote version parameters, to execute the
* appropriate check.
* </p>
* <p>
* Returning a value of <b>false</b> will tell the update process that this is NOT a new version.
* Without revision, this method will always consider a remote version at all different from
* that of the local version a new update.
* </p>
* @param localVersion the current version
* @param remoteVersion the remote version
* @return true if Updater should consider the remote version an update, false if not.
*/
public boolean shouldUpdate(String localVersion, String remoteVersion) {
return !localVersion.equalsIgnoreCase(remoteVersion);
}
/**
* Evaluate whether the version number is marked showing that it should not be updated by this program.
*
* @param version a version number to check for tags in.
* @return true if updating should be disabled.
*/
private boolean hasTag(String version) {
for (final String string : Updater.NO_UPDATE_TAG) {
if (version.contains(string)) {
return true;
}
}
return false;
}
/**
* Make a connection to the BukkitDev API and request the newest file's details.
*
* @return true if successful.
*/
private boolean read() {
try {
final URLConnection conn = this.url.openConnection();
conn.setConnectTimeout(5000);
if (this.apiKey != null) {
conn.addRequestProperty("X-API-Key", this.apiKey);
}
conn.addRequestProperty("User-Agent", Updater.USER_AGENT);
conn.setDoOutput(true);
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
final String response = reader.readLine();
final JSONArray array = (JSONArray) JSONValue.parse(response);
if (array.isEmpty()) {
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
this.result = UpdateResult.FAIL_BADID;
return false;
}
JSONObject latestUpdate = (JSONObject) array.get(array.size() - 1);
this.versionName = (String) latestUpdate.get(Updater.TITLE_VALUE);
this.versionLink = (String) latestUpdate.get(Updater.LINK_VALUE);
this.versionType = (String) latestUpdate.get(Updater.TYPE_VALUE);
this.versionGameVersion = (String) latestUpdate.get(Updater.VERSION_VALUE);
return true;
} catch (final IOException e) {
if (e.getMessage().contains("HTTP response code: 403")) {
this.plugin.getLogger().severe("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
this.plugin.getLogger().severe("Please double-check your configuration to ensure it is correct.");
this.result = UpdateResult.FAIL_APIKEY;
} else {
this.plugin.getLogger().severe("The updater could not contact dev.bukkit.org for updating.");
this.plugin.getLogger().severe("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
this.result = UpdateResult.FAIL_DBO;
}
AreaShop.debug(ExceptionUtils.getStackTrace(e));
return false;
}
}
/**
* Perform a file operation and log any errors if it fails.
* @param file file operation is performed on.
* @param result result of file operation.
* @param create true if a file is being created, false if deleted.
*/
private void fileIOOrError(File file, boolean result, boolean create) {
if (!result) {
this.plugin.getLogger().severe("The updater could not " + (create ? "create" : "delete") + " file at: " + file.getAbsolutePath());
}
}
private File[] listFilesOrError(File folder) {
File[] contents = folder.listFiles();
if (contents == null) {
this.plugin.getLogger().severe("The updater could not access files at: " + this.updateFolder.getAbsolutePath());
return new File[0];
} else {
return contents;
}
}
/**
* Called on main thread when the Updater has finished working, regardless
* of result.
*/
public interface UpdateCallback {
/**
* Called when the updater has finished working.
* @param updater The updater instance
*/
void onFinish(Updater updater);
}
private class UpdateRunnable implements Runnable {
@Override
public void run() {
runUpdater();
}
}
private void runUpdater() {
if (this.url != null && (this.read() && this.versionCheck())) {
// Obtain the results of the project's file feed
if ((this.versionLink != null) && (this.type != UpdateType.NO_DOWNLOAD)) {
String name = this.file.getName();
// If it's a zip file, it shouldn't be downloaded as the plugin's name
if (this.versionLink.endsWith(".zip")) {
name = this.versionLink.substring(this.versionLink.lastIndexOf("/") + 1);
}
this.saveFile(name);
} else {
this.result = UpdateResult.UPDATE_AVAILABLE;
}
}
if (this.callback != null) {
new BukkitRunnable() {
@Override
public void run() {
runCallback();
}
}.runTask(this.plugin);
}
}
private void runCallback() {
this.callback.onFinish(this);
}
}
@@ -0,0 +1,612 @@
package nl.evolutioncoding.areashop;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion.RegionType;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
public class Utils {
// Not used
private Utils() {}
private static YamlConfiguration config;
private static ArrayList<String> identifiers;
private static ArrayList<String> seconds;
private static ArrayList<String> minutes;
private static ArrayList<String> hours;
private static ArrayList<String> days;
private static ArrayList<String> weeks;
private static ArrayList<String> months;
private static ArrayList<String> years;
public static void initialize(YamlConfiguration pluginConfig) {
config = pluginConfig;
// Setup individual identifiers
seconds = new ArrayList<>(config.getStringList("seconds"));
minutes = new ArrayList<>(config.getStringList("minutes"));
hours = new ArrayList<>(config.getStringList("hours"));
days = new ArrayList<>(config.getStringList("days"));
weeks = new ArrayList<>(config.getStringList("weeks"));
months = new ArrayList<>(config.getStringList("months"));
years = new ArrayList<>(config.getStringList("years"));
// Setup all time identifiers
identifiers = new ArrayList<>();
identifiers.addAll(seconds);
identifiers.addAll(minutes);
identifiers.addAll(hours);
identifiers.addAll(days);
identifiers.addAll(weeks);
identifiers.addAll(months);
identifiers.addAll(years);
}
/**
* Gets the online players
* Provides backwards compatibility for 1.7- where it returns an array
* @return Online players
*/
@SuppressWarnings("unchecked")
public static Collection<? extends Player> getOnlinePlayers() {
try {
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
if(onlinePlayerMethod.getReturnType().equals(Collection.class)) {
return ((Collection<? extends Player>)onlinePlayerMethod.invoke(Bukkit.getServer()));
} else {
return Arrays.asList((Player[])onlinePlayerMethod.invoke(Bukkit.getServer()));
}
} catch(Exception ex) {
AreaShop.debug("getOnlinePlayers error: "+ex.getMessage());
}
return new HashSet<>();
}
/**
* Create a map from a location, to save it in the config
* @param location The location to transform
* @return The map with the location values
*/
public static ConfigurationSection locationToConfig(Location location, boolean setPitchYaw) {
if(location == null) {
return null;
}
ConfigurationSection result = new YamlConfiguration();
result.set("world", location.getWorld().getName());
result.set("x", location.getX());
result.set("y", location.getY());
result.set("z", location.getZ());
if(setPitchYaw) {
result.set("yaw", Float.toString(location.getYaw()));
result.set("pitch", Float.toString(location.getPitch()));
}
return result;
}
public static ConfigurationSection locationToConfig(Location location) {
return locationToConfig(location, false);
}
/**
* Create a location from a map, reconstruction from the config values
* @param config The config section to reconstruct from
* @return The location
*/
public static Location configToLocation(ConfigurationSection config) {
if(config == null
|| !config.isString("world")
|| !config.isDouble("x")
|| !config.isDouble("y")
|| !config.isDouble("z")
|| Bukkit.getWorld(config.getString("world")) == null) {
return null;
}
Location result = new Location(
Bukkit.getWorld(config.getString("world")),
config.getDouble("x"),
config.getDouble("y"),
config.getDouble("z"));
if(config.isString("yaw") && config.isString("pitch")) {
result.setPitch(Float.parseFloat(config.getString("pitch")));
result.setYaw(Float.parseFloat(config.getString("yaw")));
}
return result;
}
/**
* Create a comma-separated list
* @param input Collection of object which should be concatenated with comma's in between
* @return Innput object concatenated with comma's in between
*/
public static String createCommaSeparatedList(Collection<?> input) {
String result = "";
boolean first = true;
for(Object object : input) {
if(object != null) {
if(first) {
first = false;
result += object.toString();
} else {
result += ", " + object.toString();
}
}
}
return result;
}
/**
* Convert milliseconds to ticks
* @param milliseconds Milliseconds to convert
* @return milliseconds divided by 50 (20 ticks per second)
*/
public static long millisToTicks(long milliseconds) {
return milliseconds/50;
}
private static final BlockFace[] facings = {BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST};
/**
* Get the facing direction based on the yaw
* @param yaw The horizontal angle that for example the player is looking
* @return The Block Face of the angle
*/
public static BlockFace yawToFacing(float yaw) {
return facings[Math.round(yaw / 45f) & 0x7];
}
// ======================================================================
// Methods to get WorldGuard or AreaShop regions by location or selection
// ======================================================================
/**
* Get all AreaShop regions intersecting with a WorldEdit selection
* @param selection The selection to check
* @return A list with all the AreaShop regions intersecting with the selection
*/
public static List<GeneralRegion> getASRegionsInSelection(Selection selection) {
ArrayList<GeneralRegion> result = new ArrayList<>();
for(ProtectedRegion region : getWERegionsInSelection(selection)) {
GeneralRegion asRegion = AreaShop.getInstance().getFileManager().getRegion(region.getId());
if(asRegion != null) {
result.add(asRegion);
}
}
return result;
}
/**
* Get all AreaShop regions containing a location
* @param location The location to check
* @return A list with all the AreaShop regions that contain the location
*/
public static List<GeneralRegion> getASRegionsByLocation(Location location) {
Selection selection = new CuboidSelection(location.getWorld(), location, location);
return getASRegionsInSelection(selection);
}
/**
* Get all WorldGuard regions intersecting with a WorldEdit selection
* @param selection The selection to check
* @return A list with all the WorldGuard regions intersecting with the selection
*/
public static List<ProtectedRegion> getWERegionsInSelection(Selection selection) {
// Get all regions inside or intersecting with the WorldEdit selection of the player
World world = selection.getWorld();
RegionManager regionManager = AreaShop.getInstance().getWorldGuard().getRegionManager(world);
ArrayList<ProtectedRegion> result = new ArrayList<>();
Location selectionMin = selection.getMinimumPoint();
Location selectionMax = selection.getMaximumPoint();
for(ProtectedRegion region : regionManager.getRegions().values()) {
BlockVector regionMin = region.getMinimumPoint();
BlockVector regionMax = region.getMaximumPoint();
if(
( // x part, resolves to true if the selection and region overlap anywhere on the x-axis
(regionMin.getBlockX() <= selectionMax.getBlockX() && regionMin.getBlockX() >= selectionMin.getBlockX())
|| (regionMax.getBlockX() <= selectionMax.getBlockX() && regionMax.getBlockX() >= selectionMin.getBlockX())
|| (selectionMin.getBlockX() >= regionMin.getBlockX() && selectionMin.getBlockX() <= regionMax.getBlockX())
|| (selectionMax.getBlockX() >= regionMin.getBlockX() && selectionMax.getBlockX() <= regionMax.getBlockX())
) && ( // Y part, resolves to true if the selection and region overlap anywhere on the y-axis
(regionMin.getBlockY() <= selectionMax.getBlockY() && regionMin.getBlockY() >= selectionMin.getBlockY())
|| (regionMax.getBlockY() <= selectionMax.getBlockY() && regionMax.getBlockY() >= selectionMin.getBlockY())
|| (selectionMin.getBlockY() >= regionMin.getBlockY() && selectionMin.getBlockY() <= regionMax.getBlockY())
|| (selectionMax.getBlockY() >= regionMin.getBlockY() && selectionMax.getBlockY() <= regionMax.getBlockY())
) && ( // Z part, resolves to true if the selection and region overlap anywhere on the z-axis
(regionMin.getBlockZ() <= selectionMax.getBlockZ() && regionMin.getBlockZ() >= selectionMin.getBlockZ())
|| (regionMax.getBlockZ() <= selectionMax.getBlockZ() && regionMax.getBlockZ() >= selectionMin.getBlockZ())
|| (selectionMin.getBlockZ() >= regionMin.getBlockZ() && selectionMin.getBlockZ() <= regionMax.getBlockZ())
|| (selectionMax.getBlockZ() >= regionMin.getBlockZ() && selectionMax.getBlockZ() <= regionMax.getBlockZ())
)
) {
result.add(region);
}
}
return result;
}
/**
* Get a list of regions around a location
* - Returns highest priority, child instead of parent regions
* @param location The location to check for regions
* @return empty list if no regions found, 1 member if 1 region is a priority, more if regions with the same priority
*/
public static List<ProtectedRegion> getApplicableRegions(Location location) {
List<ProtectedRegion> result = new ArrayList<>();
Set<ProtectedRegion> regions = AreaShop.getInstance().getWorldGuardHandler().getApplicableRegionsSet(location);
if(regions != null) {
boolean first = true;
for(ProtectedRegion pr : regions) {
if(first) {
result.add(pr);
first = false;
} else {
if(pr.getPriority() > result.get(0).getPriority()) {
result.clear();
result.add(pr);
} else if(pr.getParent() != null && pr.getParent().equals(result.get(0))) {
result.clear();
result.add(pr);
} else {
result.add(pr);
}
}
}
}
return result;
}
// Methods to get the most important AreaShop regions at a certain location
public static List<RentRegion> getApplicableRentRegions(Location location) {
List<RentRegion> result = new ArrayList<>();
for(GeneralRegion region : getApplicableASRegions(location, RegionType.RENT)) {
result.add((RentRegion)region);
}
return result;
}
public static List<BuyRegion> getApplicableBuyRegions(Location location) {
List<BuyRegion> result = new ArrayList<>();
for(GeneralRegion region : getApplicableASRegions(location, RegionType.BUY)) {
result.add((BuyRegion)region);
}
return result;
}
public static List<GeneralRegion> getAllApplicableRegions(Location location) {
return getApplicableASRegions(location, null);
}
public static List<GeneralRegion> getApplicableASRegions(Location location, RegionType type) {
List<GeneralRegion> result = new ArrayList<>();
Set<ProtectedRegion> regions = AreaShop.getInstance().getWorldGuardHandler().getApplicableRegionsSet(location);
if(regions != null) {
List<GeneralRegion> candidates = new ArrayList<>();
for(ProtectedRegion pr : regions) {
GeneralRegion region = AreaShop.getInstance().getFileManager().getRegion(pr.getId());
if(region != null && (
(type == RegionType.RENT && region.isRentRegion())
|| (type == RegionType.BUY && region.isBuyRegion())
|| type == null)) {
candidates.add(region);
}
}
boolean first = true;
for(GeneralRegion region : candidates) {
if(region == null) {
AreaShop.debug("skipped null region");
continue;
}
if(first) {
result.add(region);
first = false;
} else {
if(region.getRegion().getPriority() > result.get(0).getRegion().getPriority()) {
result.clear();
result.add(region);
} else if(region.getRegion().getParent() != null && region.getRegion().getParent().equals(result.get(0).getRegion())) {
result.clear();
result.add(region);
} else {
result.add(region);
}
}
}
}
return new ArrayList<>(result);
}
/**
* Convert color and formatting codes to bukkit values
* @param input Start string with color and formatting codes in it
* @return String with the color and formatting codes in the bukkit format
*/
public static String applyColors(String input) {
String result = null;
if(input != null) {
result = ChatColor.translateAlternateColorCodes('&', input);
}
return result;
}
/**
* Format the currency amount with the characters before and after
* @param amount Amount of money to format
* @return Currency character format string
*/
public static String formatCurrency(double amount) {
String before = config.getString("moneyCharacter");
before = before.replace(AreaShop.currencyEuro, "\u20ac");
String after = config.getString("moneyCharacterAfter");
after = after.replace(AreaShop.currencyEuro, "\u20ac");
String result;
// Check for infinite and NaN
if(Double.isInfinite(amount)) {
result = "\u221E"; // Infinite symbol
} else if(Double.isNaN(amount)) {
result = "NaN";
} else {
// Add metric
double metricAbove = config.getDouble("metricSuffixesAbove");
if(metricAbove != -1 && amount >= metricAbove) {
if(amount >= 1000000000000000000000000.0) {
amount = amount/1000000000000000000000000.0;
after = "Y"+after;
} else if(amount >= 1000000000000000000000.0) {
amount = amount/1000000000000000000000.0;
after = "Z"+after;
} else if(amount >= 1000000000000000000.0) {
amount = amount/1000000000000000000.0;
after = "E"+after;
} else if(amount >= 1000000000000000.0) {
amount = amount/1000000000000000.0;
after = "P"+after;
} else if(amount >= 1000000000000.0) {
amount = amount/1000000000000.0;
after = "T"+after;
} else if(amount >= 1000000000.0) {
amount = amount/1000000000.0;
after = "G"+after;
} else if(amount >= 1000000.0) {
amount = amount/1000000.0;
after = "M"+after;
} else if(amount >= 1000.0) {
amount = amount/1000.0;
after = "k"+after;
}
BigDecimal bigDecimal = new BigDecimal(amount);
if(bigDecimal.toString().contains(".")) {
int frontLength = bigDecimal.toString().substring(0, bigDecimal.toString().indexOf('.')).length();
bigDecimal = bigDecimal.setScale(config.getInt("fractionalNumbers")+(3-frontLength), RoundingMode.HALF_UP);
}
result = bigDecimal.toString();
} else {
BigDecimal bigDecimal = new BigDecimal(amount);
bigDecimal = bigDecimal.setScale(config.getInt("fractionalNumbers"), RoundingMode.HALF_UP);
amount = bigDecimal.doubleValue();
result = bigDecimal.toString();
if(config.getBoolean("hideEmptyFractionalPart") && (amount%1.0) == 0.0 && result.contains(".")) {
result = result.substring(0, result.indexOf('.'));
}
}
}
result = result.replace(".", config.getString("decimalMark"));
return before+result+after;
}
/**
* Checks if the string is a correct time period
* @param time String that has to be checked
* @return true if format is correct, false if not
*/
public static boolean checkTimeFormat(String time) {
// Check if the string is not empty and check the length
if(time == null || time.length() <= 1 || time.indexOf(' ') == -1 || time.indexOf(' ') >= (time.length()-1)) {
return false;
}
// Check if the suffix is one of these values
String suffix = time.substring(time.indexOf(' ')+1, time.length());
if(!identifiers.contains(suffix)) {
return false;
}
// check if the part before the space is a number
String prefix = time.substring(0, (time.indexOf(' ')));
return prefix.matches("\\d+");
}
/**
* Methode to tranlate a duration string to a millisecond value
* @param duration The duration string
* @return The duration in milliseconds translated from the durationstring, or if it is invalid then 0
*/
public static long durationStringToLong(String duration) {
if(duration == null) {
return 0;
} else if(duration.equalsIgnoreCase("disabled") || duration.equalsIgnoreCase("unlimited")) {
return -1;
} else if(duration.indexOf(' ') == -1) {
return 0;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(0);
String durationString = duration.substring(duration.indexOf(' ')+1, duration.length());
int durationInt = 0;
try {
durationInt = Integer.parseInt(duration.substring(0, duration.indexOf(' ')));
} catch(NumberFormatException exception) {
// No Number found, add zero
}
if(seconds.contains(durationString)) {
calendar.add(Calendar.SECOND, durationInt);
} else if(minutes.contains(durationString)) {
calendar.add(Calendar.MINUTE, durationInt);
} else if(hours.contains(durationString)) {
calendar.add(Calendar.HOUR, durationInt);
} else if(days.contains(durationString)) {
calendar.add(Calendar.DAY_OF_MONTH, durationInt);
} else if(weeks.contains(durationString)) {
calendar.add(Calendar.DAY_OF_MONTH, durationInt*7);
} else if(months.contains(durationString)) {
calendar.add(Calendar.MONTH, durationInt);
} else if(years.contains(durationString)) {
calendar.add(Calendar.YEAR, durationInt);
}
return calendar.getTimeInMillis();
}
// LEGACY TIME INPUT CONVERSION
/**
* Get setting from config that could be only a number indicating seconds
* or a string indicating a duration string
* @param path Path of the setting to read
* @return milliseconds that the setting indicates
*/
public static long getDurationFromSecondsOrString(String path) {
if(config.isLong(path) || config.isInt(path)) {
long setting = config.getLong(path);
if(setting != -1) {
setting = setting*1000;
}
return setting;
} else {
return durationStringToLong(config.getString(path));
}
}
/**
* Get setting from config that could be only a number indicating minutes
* or a string indicating a duration string
* @param path Path of the setting to read
* @return milliseconds that the setting indicates
*/
public static long getDurationFromMinutesOrString(String path) {
if(config.isLong(path) || config.isInt(path)) {
long setting = config.getLong(path);
if(setting != -1) {
setting = setting*60*1000;
}
return setting;
} else {
return durationStringToLong(config.getString(path));
}
}
/**
* Parse a time setting that could be minutes or a duration string
* @param input The string to parse
* @return milliseconds that the string indicates
*/
public static long getDurationFromMinutesOrStringInput(String input) {
long number;
try {
number = Long.parseLong(input);
if(number != -1) {
number = number*60*1000;
}
return number;
} catch(NumberFormatException e) {
return durationStringToLong(input);
}
}
/**
* Parse a time setting that could be seconds or a duration string
* @param input The string to parse
* @return seconds that the string indicates
*/
public static long getDurationFromSecondsOrStringInput(String input) {
long number;
try {
number = Long.parseLong(input);
if(number != -1) {
number = number*1000;
}
return number;
} catch(NumberFormatException e) {
return durationStringToLong(input);
}
}
// NAME <-> UUID CONVERSION
/**
* Conversion to name by uuid
* @param uuid The uuid in string format
* @return the name of the player
*/
public static String toName(String uuid) {
String result = "";
if(uuid != null) {
try {
UUID parsed = UUID.fromString(uuid);
result = toName(parsed);
} catch(IllegalArgumentException e) {
// Incorrect UUID
}
}
return result;
}
/**
* Conversion to name by uuid object
* @param uuid The uuid in string format
* @return the name of the player
*/
public static String toName(UUID uuid) {
if(uuid == null) {
return "";
} else {
String name = Bukkit.getOfflinePlayer(uuid).getName();
if(name != null) {
return name;
}
return "";
}
}
/**
* Conversion from name to uuid
* @param name The name of the player
* @return The uuid of the player
*/
@SuppressWarnings("deprecation") // Fake deprecation by Bukkit to inform developers, method will stay
public static String toUUID(String name) {
if(name == null) {
return null;
} else {
return Bukkit.getOfflinePlayer(name).getUniqueId().toString();
}
}
}
@@ -0,0 +1,239 @@
package nl.evolutioncoding.areashop.commands;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.managers.FileManager.AddResult;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion.RegionEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion.RegionType;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.List;
public class AddCommand extends CommandAreaShop {
public AddCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop add";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.createrent") || target.hasPermission("areashop.createbuy")) {
return plugin.getLanguageManager().getLang("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")) {
plugin.message(sender, "add-noPermission");
return;
}
if(args.length < 2 || args[1] == null || (!"rent".equals(args[1].toLowerCase()) && !"buy".equals(args[1].toLowerCase()))) {
plugin.message(sender, "add-help");
return;
}
List<ProtectedRegion> regions = new ArrayList<>();
World world;
Player player = null;
if(sender instanceof Player) {
player = (Player)sender;
}
if(args.length == 2) {
if(player == null) {
plugin.message(sender, "cmd-weOnlyByPlayer");
return;
}
Selection selection = plugin.getWorldEdit().getSelection(player);
if(selection == null) {
plugin.message(player, "cmd-noSelection");
return;
}
world = selection.getWorld();
regions = Utils.getWERegionsInSelection(selection);
if(regions.size() == 0) {
plugin.message(player, "cmd-noWERegionsFound");
return;
}
} else {
if(player != null) {
if(args.length == 4) {
world = Bukkit.getWorld(args[3]);
if(world == null) {
plugin.message(sender, "add-incorrectWorld", args[3]);
return;
}
} else {
world = ((Player)sender).getWorld();
}
} else {
if(args.length < 4) {
plugin.message(sender, "add-specifyWorld");
return;
} else {
world = Bukkit.getWorld(args[3]);
if(world == null) {
plugin.message(sender, "add-incorrectWorld", args[3]);
return;
}
}
}
ProtectedRegion region = plugin.getWorldGuard().getRegionManager(world).getRegion(args[2]);
if(region == null) {
plugin.message(sender, "add-noRegion", args[2]);
return;
}
regions.add(region);
}
final boolean isRent = "rent".equals(args[1].toLowerCase());
final List<ProtectedRegion> finalRegions = regions;
final Player finalPlayer = player;
final World finalWorld = world;
AreaShop.debug("Starting add task with " + regions.size() + " regions");
new BukkitRunnable() {
private int current = 0;
private ArrayList<String> namesSuccess = new ArrayList<>();
private ArrayList<String> namesAlready = new ArrayList<>();
private ArrayList<String> namesBlacklisted = new ArrayList<>();
private ArrayList<String> namesNoPermission = new ArrayList<>();
private ArrayList<String> namesExternal = new ArrayList<>();
@Override
public void run() {
for(int i=0; i<plugin.getConfig().getInt("adding.regionsPerTick"); i++) {
if(current < finalRegions.size()) {
ProtectedRegion region = finalRegions.get(current);
// Determine if the player is an owner or member of the region
boolean isMember = finalPlayer != null && plugin.getWorldGuardHandler().containsMember(region, finalPlayer.getUniqueId());
boolean isOwner = finalPlayer != null && plugin.getWorldGuardHandler().containsMember(region, finalPlayer.getUniqueId());
String type;
if(isRent) {
type = "rent";
} else {
type = "buy";
}
AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, isRent ? RegionType.RENT : RegionType.BUY);
if(result == AddResult.ALREADYADDED) {
namesAlready.add(region.getId());
} else if(result == AddResult.BLACKLISTED) {
namesBlacklisted.add(region.getId());
} else if(result == AddResult.NOPERMISSION) {
namesNoPermission.add(region.getId());
} else {
// Check if the player should be landlord
boolean landlord = (!sender.hasPermission("areashop.create" + type)
&& ((sender.hasPermission("areashop.create" + type + ".owner") && isOwner)
|| (sender.hasPermission("areashop.create" + type + ".member") && isMember)));
if(isRent) {
RentRegion rent = new RentRegion(plugin, region.getId(), finalWorld);
// Set landlord
if(landlord) {
rent.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
}
// Run commands
rent.runEventCommands(RegionEvent.CREATED, true);
plugin.getFileManager().addRent(rent);
rent.handleSchematicEvent(RegionEvent.CREATED);
rent.update();
// Run commands
rent.runEventCommands(RegionEvent.CREATED, false);
namesSuccess.add(region.getId());
} else {
BuyRegion buy = new BuyRegion(plugin, region.getId(), finalWorld);
// Set landlord
if(landlord) {
buy.setLandlord(finalPlayer.getUniqueId(), finalPlayer.getName());
}
// Run commands
buy.runEventCommands(RegionEvent.CREATED, true);
plugin.getFileManager().addBuy(buy);
buy.handleSchematicEvent(RegionEvent.CREATED);
buy.update();
// Run commands
buy.runEventCommands(RegionEvent.CREATED, false);
namesSuccess.add(region.getId());
}
}
current++;
}
}
if(current >= finalRegions.size()) {
if(!namesSuccess.isEmpty()) {
plugin.message(sender, "add-success", args[1], Utils.createCommaSeparatedList(namesSuccess));
}
if(!namesAlready.isEmpty()) {
plugin.message(sender, "add-failed", Utils.createCommaSeparatedList(namesAlready));
}
if(!namesBlacklisted.isEmpty()) {
plugin.message(sender, "add-blacklisted", Utils.createCommaSeparatedList(namesBlacklisted));
}
if(!namesNoPermission.isEmpty()) {
plugin.message(sender, "add-noPermissionRegions", Utils.createCommaSeparatedList(namesNoPermission));
plugin.message(sender, "add-noPermissionOwnerMember");
}
this.cancel();
}
}
}.runTaskTimer(plugin, 1, 1);
}
@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.getWorldGuard().getRegionManager(player.getWorld()).getRegions().values()) {
result.add(region.getId());
}
}
}
}
return result;
}
}
@@ -0,0 +1,145 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class AddfriendCommand extends CommandAreaShop {
public AddfriendCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop addfriend";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.addfriendall")) {
return plugin.getLanguageManager().getLang("help-addFriendAll");
} else if(target.hasPermission("areashop.addfriend")) {
return plugin.getLanguageManager().getLang("help-addFriend");
}
return null;
}
@SuppressWarnings("deprecation")
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
plugin.message(sender, "addfriend-noPermission");
return;
}
if(args.length < 2) {
plugin.message(sender, "addfriend-help");
return;
}
GeneralRegion region;
if(args.length <= 2) {
if (sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = plugin.getFileManager().getRegion(args[2]);
if(region == null) {
plugin.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if(sender.hasPermission("areashop.addfriendall")) {
if((region.isRentRegion() && !((RentRegion)region).isRented())
|| (region.isBuyRegion() && !((BuyRegion)region).isSold())) {
plugin.message(sender, "addfriend-noOwner", region);
return;
}
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(friend.getLastPlayed() == 0 && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
plugin.message(sender, "addfriend-notVisited", args[1], region);
return;
}
if(region.getFriends().contains(friend.getUniqueId())) {
plugin.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
return;
}
if(region.isOwner(friend.getUniqueId())) {
plugin.message(sender, "addfriend-self", friend.getName(), region);
return;
}
region.addFriend(friend.getUniqueId());
region.update();
plugin.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 && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
plugin.message(sender, "addfriend-notVisited", args[1], region);
return;
}
if(region.getFriends().contains(friend.getUniqueId())) {
plugin.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
return;
}
if(region.isOwner(friend.getUniqueId())) {
plugin.message(sender, "addfriend-self", friend.getName(), region);
return;
}
region.addFriend(friend.getUniqueId());
region.update();
plugin.message(sender, "addfriend-success", friend.getName(), region);
} else {
plugin.message(sender, "addfriend-noPermissionOther", region);
}
} else {
plugin.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(plugin.getFileManager().getRegionNames());
}
return result;
}
}
@@ -1,22 +1,19 @@
package nl.evolutioncoding.AreaShop.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
package nl.evolutioncoding.areashop.commands;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.material.Sign;
import org.bukkit.util.BlockIterator;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class AddsignCommand extends CommandAreaShop {
@@ -38,16 +35,17 @@ public class AddsignCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.addsign")) {
plugin.message(sender, "addsign-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
}
Player player = (Player)sender;
if(!player.hasPermission("areashop.addsign")) {
plugin.message(sender, "addsign-noPermission");
return;
}
// Get the sign
Block block = null;
BlockIterator blockIterator = new BlockIterator(player, 100);
@@ -62,7 +60,7 @@ public class AddsignCommand extends CommandAreaShop {
return;
}
GeneralRegion region = null;
GeneralRegion region;
if(args.length > 1) {
// Get region by argument
region = plugin.getFileManager().getRegion(args[1]);
@@ -72,7 +70,7 @@ public class AddsignCommand extends CommandAreaShop {
}
} else {
// Get region by sign position
List<GeneralRegion> regions = plugin.getFileManager().getASRegionsInSelection(new CuboidSelection(block.getWorld(), block.getLocation(), block.getLocation()));
List<GeneralRegion> regions = Utils.getASRegionsInSelection(new CuboidSelection(block.getWorld(), block.getLocation(), block.getLocation()));
if(regions.isEmpty()) {
plugin.message(sender, "addsign-noRegions");
return;
@@ -86,35 +84,34 @@ public class AddsignCommand extends CommandAreaShop {
String profile = null;
if(args.length > 2) {
profile = args[2];
Set<String> profiles = plugin.config().getConfigurationSection("signProfiles").getKeys(false);
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
if(!profiles.contains(profile)) {
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles));
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
return;
}
}
GeneralRegion signRegion = plugin.getFileManager().getRegionBySignLocation(block.getLocation());
if(signRegion != null) {
plugin.message(sender, "addsign-alreadyRegistered", signRegion.getName());
plugin.message(sender, "addsign-alreadyRegistered", signRegion);
return;
}
region.addSign(block.getLocation(), block.getType(), sign.getFacing(), profile);
if(profile == null) {
plugin.message(sender, "addsign-success", region.getName());
plugin.message(sender, "addsign-success", region);
} else {
plugin.message(sender, "addsign-successProfile", region.getName(), profile);
plugin.message(sender, "addsign-successProfile", profile, region);
}
region.updateSigns();
region.save();
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
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.config().getStringList("signProfiles"));
result.addAll(plugin.getConfig().getStringList("signProfiles"));
}
return result;
}
@@ -1,16 +1,14 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.BuyRegion;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class BuyCommand extends CommandAreaShop {
public BuyCommand(AreaShop plugin) {
@@ -31,7 +29,11 @@ public class BuyCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.buy")) {
plugin.message(sender, "buy-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
@@ -46,22 +48,20 @@ public class BuyCommand extends CommandAreaShop {
}
} else {
// get the region by location
List<GeneralRegion> regions = plugin.getFileManager().getApplicalbeASRegions(player.getLocation());
if(regions.size() != 1) {
plugin.message(sender, "buy-help");
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
} else {
if(!regions.get(0).isBuyRegion()) {
plugin.message(sender, "buy-notBuyable");
} else {
((BuyRegion)regions.get(0)).buy(player);
}
regions.get(0).buy(player);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(!region.isSold()) {
@@ -1,12 +1,12 @@
package nl.evolutioncoding.AreaShop.commands;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract class for generalising command classes
*/
@@ -38,11 +38,13 @@ public abstract class CommandAreaShop {
* @param start The already given start of the command
* @return A collection with all the possibilities for argument to complete
*/
public abstract List<String> getTabCompleteList(int toComplete, String[] start);
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
* @return The string that should be in front of the command for this class to act
*/
public abstract String getCommandStart();
@@ -56,10 +58,9 @@ public abstract class CommandAreaShop {
/**
* Execute a (sub)command if the conditions are met
* @param sender The commandSender that executed the command
* @param commandAreaShop The command that has been executed
* @param args The arguments that are given
*/
public abstract void execute(CommandSender sender, Command command, String[] args);
public abstract void execute(CommandSender sender, String[] args);
@@ -1,19 +1,18 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.BuyRegion;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.RentRegion;
import org.bukkit.command.Command;
import com.sk89q.worldedit.bukkit.selections.Selection;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.events.notify.RemovedRegionEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.bukkit.selections.Selection;
import java.util.ArrayList;
import java.util.List;
public class DelCommand extends CommandAreaShop {
@@ -35,8 +34,12 @@ public class DelCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
if(!sender.hasPermission("areashop.destroybuy") && !sender.hasPermission("areashop.destroyrent")) {
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")) {
plugin.message(sender, "del-noPermission");
return;
}
@@ -52,30 +55,32 @@ public class DelCommand extends CommandAreaShop {
plugin.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = plugin.getFileManager().getASRegionsInSelection(selection);
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
if(regions == null || regions.size() == 0) {
plugin.message(player, "cmd-noRegionsFound");
return;
}
// Start removing the region that he has permission for
ArrayList<String> namesSuccess = new ArrayList<String>();
ArrayList<String> namesFailed = new ArrayList<String>();
// Start removing the regions that he has permission for
ArrayList<String> namesSuccess = new ArrayList<>();
ArrayList<String> namesFailed = new ArrayList<>();
for(GeneralRegion region : regions) {
boolean isLandlord = region.isLandlord(((Player)sender).getUniqueId());
if(region.isRentRegion()) {
if(!sender.hasPermission("areashop.destroyrent")) {
if(!sender.hasPermission("areashop.destroyrent") && !(isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
namesFailed.add(region.getName());
} else {
plugin.getFileManager().removeRent((RentRegion)region, true);
namesSuccess.add(region.getName());
}
} else if(region.isBuyRegion()) {
if(!sender.hasPermission("areashop.destroybuy")) {
if(!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
namesFailed.add(region.getName());
} else {
plugin.getFileManager().removeBuy((BuyRegion)region, true);
namesSuccess.add(region.getName());
}
}
}
Bukkit.getPluginManager().callEvent(new RemovedRegionEvent(region));
}
// send messages
if(namesSuccess.size() != 0) {
@@ -90,30 +95,31 @@ public class DelCommand extends CommandAreaShop {
plugin.message(sender, "del-noRegion", args[1]);
return;
}
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId());
if(region.isRentRegion()) {
/* Remove the rent if the player has permission */
if(sender.hasPermission("areashop.destroyrent")) {
// Remove the rent if the player has permission
if(sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
plugin.getFileManager().removeRent((RentRegion)region, true);
plugin.message(sender, "destroy-successRent", region.getName());
plugin.message(sender, "destroy-successRent", region);
} else {
plugin.message(sender, "destroy-noPermissionRent");
plugin.message(sender, "destroy-noPermissionRent", region);
}
} else if(region.isBuyRegion()) {
/* Remove the buy if the player has permission */
if(sender.hasPermission("areashop.destroybuy")) {
// Remove the buy if the player has permission
if(sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
plugin.getFileManager().removeBuy((BuyRegion)region, true);
plugin.message(sender, "destroy-successBuy", region.getName());
plugin.message(sender, "destroy-successBuy", region);
} else {
plugin.message(sender, "destroy-noPermissionBuy");
plugin.message(sender, "destroy-noPermissionBuy", region);
}
}
Bukkit.getPluginManager().callEvent(new RemovedRegionEvent(region));
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getRegionNames();
}
@@ -0,0 +1,127 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class DelfriendCommand extends CommandAreaShop {
public DelfriendCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop delfriend";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.delfriendall")) {
return plugin.getLanguageManager().getLang("help-delFriendAll");
} else if(target.hasPermission("areashop.delfriend")) {
return plugin.getLanguageManager().getLang("help-delFriend");
}
return null;
}
@SuppressWarnings("deprecation")
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
plugin.message(sender, "delfriend-noPermission");
return;
}
if(args.length < 2) {
plugin.message(sender, "delfriend-help");
return;
}
GeneralRegion region;
if(args.length <= 2) {
if (sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = plugin.getFileManager().getRegion(args[2]);
if(region == null) {
plugin.message(sender, "cmd-notRegistered", args[2]);
return;
}
}
if(sender.hasPermission("areashop.delfriendall")) {
if((region.isRentRegion() && !((RentRegion)region).isRented())
|| (region.isBuyRegion() && !((BuyRegion)region).isSold())) {
plugin.message(sender, "delfriend-noOwner", region);
return;
}
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
if(!region.getFriends().contains(friend.getUniqueId())) {
plugin.message(sender, "delfriend-notAdded", friend.getName(), region);
return;
}
region.deleteFriend(friend.getUniqueId());
region.update();
plugin.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.getFriends().contains(friend.getUniqueId())) {
plugin.message(sender, "delfriend-notAdded", friend.getName(), region);
return;
}
region.deleteFriend(friend.getUniqueId());
region.update();
plugin.message(sender, "delfriend-success", friend.getName(), region);
} else {
plugin.message(sender, "delfriend-noPermissionOther", region);
}
} else {
plugin.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(plugin.getFileManager().getRegionNames());
}
return result;
}
}
@@ -1,18 +1,16 @@
package nl.evolutioncoding.AreaShop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator;
import java.util.ArrayList;
import java.util.List;
public class DelsignCommand extends CommandAreaShop {
public DelsignCommand(AreaShop plugin) {
@@ -33,16 +31,17 @@ public class DelsignCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.delsign")) {
plugin.message(sender, "delsign-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(!player.hasPermission("areashop.delsign")) {
plugin.message(sender, "delsign-noPermission");
return;
}
// Get the sign
Block block = null;
BlockIterator blockIterator = new BlockIterator(player, 100);
@@ -61,15 +60,14 @@ public class DelsignCommand extends CommandAreaShop {
plugin.message(sender, "delsign-noRegion");
return;
}
plugin.message(sender, "delsign-success", region.getName());
plugin.message(sender, "delsign-success", region);
region.removeSign(block.getLocation());
region.updateSigns();
region.save();
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
return new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
}
}
@@ -0,0 +1,183 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class FindCommand extends CommandAreaShop {
public FindCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop find";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.find")) {
return plugin.getLanguageManager().getLang("help-find");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.find")) {
plugin.message(sender, "find-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
if(args.length <= 1 || args[1] == null || (!args[1].equalsIgnoreCase("buy") && !args[1].equalsIgnoreCase("rent"))) {
plugin.message(sender, "find-help");
return;
}
Player player = (Player)sender;
double balance = 0.0;
if(plugin.getEconomy() != null) {
balance = plugin.getEconomy().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) {
plugin.message(sender, "find-wrongMaxPrice", args[2]);
return;
}
}
// Parse optional group argument
if(args.length >= 4) {
group = plugin.getFileManager().getGroup(args[3]);
if(group == null) {
plugin.message(sender, "find-wrongGroup", args[3]);
return;
}
}
if(args[1].equalsIgnoreCase("buy")) {
List<BuyRegion> regions = plugin.getFileManager().getBuys();
List<BuyRegion> results = new ArrayList<>();
for(BuyRegion region : regions) {
if(!region.isSold()
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
&& (group == null || group.isMember(region))) {
results.add(region);
}
}
if(!results.isEmpty()) {
// Draw a random one
BuyRegion region = results.get(new Random().nextInt(results.size()));
String onlyInGroup = "";
if(group != null) {
onlyInGroup = plugin.getLanguageManager().getLang("find-onlyInGroup", args[3]);
}
if(maxPriceSet) {
plugin.message(player, "find-successMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup, region);
} else {
plugin.message(player, "find-success", "buy", Utils.formatCurrency(balance), onlyInGroup, region);
}
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else {
String onlyInGroup = "";
if(group != null) {
onlyInGroup = plugin.getLanguageManager().getLang("find-onlyInGroup", args[3]);
}
if(maxPriceSet) {
plugin.message(player, "find-noneFoundMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup);
} else {
plugin.message(player, "find-noneFound", "buy", Utils.formatCurrency(balance), onlyInGroup);
}
}
} else {
List<RentRegion> regions = plugin.getFileManager().getRents();
List<RentRegion> results = new ArrayList<>();
for(RentRegion region : regions) {
if(!region.isRented()
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
&& (group == null || group.isMember(region))) {
results.add(region);
}
}
if(!results.isEmpty()) {
// Draw a random one
RentRegion region = results.get(new Random().nextInt(results.size()));
String onlyInGroup = "";
if(group != null) {
onlyInGroup = plugin.getLanguageManager().getLang("find-onlyInGroup", args[3]);
}
if(maxPriceSet) {
plugin.message(player, "find-successMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup, region);
} else {
plugin.message(player, "find-success", "rent", Utils.formatCurrency(balance), onlyInGroup, region);
}
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else {
String onlyInGroup = "";
if(group != null) {
onlyInGroup = plugin.getLanguageManager().getLang("find-onlyInGroup", args[3]);
}
if(maxPriceSet) {
plugin.message(player, "find-noneFoundMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup);
} else {
plugin.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;
}
}
@@ -1,18 +1,15 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.RegionGroup;
import org.bukkit.command.Command;
import com.sk89q.worldedit.bukkit.selections.Selection;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.bukkit.selections.Selection;
import java.util.ArrayList;
import java.util.List;
public class GroupaddCommand extends CommandAreaShop {
@@ -34,7 +31,7 @@ public class GroupaddCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupadd")) {
plugin.message(sender, "groupadd-noPermission");
return;
@@ -59,16 +56,18 @@ public class GroupaddCommand extends CommandAreaShop {
plugin.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = plugin.getFileManager().getASRegionsInSelection(selection);
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
if(regions.size() == 0) {
plugin.message(player, "cmd-noRegionsFound");
return;
}
ArrayList<String> namesSuccess = new ArrayList<String>();
ArrayList<String> namesFailed = new ArrayList<String>();
}
ArrayList<String> namesSuccess = new ArrayList<>();
ArrayList<String> namesFailed = new ArrayList<>();
ArrayList<GeneralRegion> toUpdate = new ArrayList<>();
for(GeneralRegion region : regions) {
if(group.addMember(region)) {
namesSuccess.add(region.getName());
toUpdate.add(region);
} else {
namesFailed.add(region.getName());
}
@@ -79,6 +78,8 @@ public class GroupaddCommand extends CommandAreaShop {
if(namesFailed.size() != 0) {
plugin.message(player, "groupadd-weFailed", group.getName(), Utils.createCommaSeparatedList(namesFailed));
}
// Update all regions, this does it in a task, updating them without lag
plugin.getFileManager().updateRegions(toUpdate, player);
} else {
GeneralRegion region = plugin.getFileManager().getRegion(args[2]);
if(region == null) {
@@ -86,16 +87,17 @@ public class GroupaddCommand extends CommandAreaShop {
return;
}
if(group.addMember(region)) {
plugin.message(sender, "groupadd-success", region.getName(), group.getName(), group.getMembers().size());
region.update();
plugin.message(sender, "groupadd-success", group.getName(), group.getMembers().size(), region);
} else {
plugin.message(sender, "groupadd-failed", region.getName(), group.getName());
plugin.message(sender, "groupadd-failed", group.getName(), region);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getGroupNames();
} else if(toComplete == 3) {
@@ -1,18 +1,15 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.RegionGroup;
import org.bukkit.command.Command;
import com.sk89q.worldedit.bukkit.selections.Selection;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.bukkit.selections.Selection;
import java.util.ArrayList;
import java.util.List;
public class GroupdelCommand extends CommandAreaShop {
@@ -34,7 +31,7 @@ public class GroupdelCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupdel")) {
plugin.message(sender, "groupdel-noPermission");
return;
@@ -59,16 +56,18 @@ public class GroupdelCommand extends CommandAreaShop {
plugin.message(player, "cmd-noSelection");
return;
}
List<GeneralRegion> regions = plugin.getFileManager().getASRegionsInSelection(selection);
List<GeneralRegion> regions = Utils.getASRegionsInSelection(selection);
if(regions.size() == 0) {
plugin.message(player, "cmd-noRegionsFound");
return;
}
ArrayList<String> namesSuccess = new ArrayList<String>();
ArrayList<String> namesFailed = new ArrayList<String>();
}
ArrayList<String> namesSuccess = new ArrayList<>();
ArrayList<String> namesFailed = new ArrayList<>();
ArrayList<GeneralRegion> toUpdate = new ArrayList<>();
for(GeneralRegion region : regions) {
if(group.removeMember(region)) {
namesSuccess.add(region.getName());
toUpdate.add(region);
} else {
namesFailed.add(region.getName());
}
@@ -79,6 +78,9 @@ public class GroupdelCommand extends CommandAreaShop {
if(namesFailed.size() != 0) {
plugin.message(player, "groupdel-weFailed", group.getName(), Utils.createCommaSeparatedList(namesFailed));
}
// Update all regions, this does it in a task, updating them without lag
plugin.getFileManager().updateRegions(toUpdate, player);
group.saveRequired();
} else {
GeneralRegion region = plugin.getFileManager().getRegion(args[2]);
if(region == null) {
@@ -86,16 +88,17 @@ public class GroupdelCommand extends CommandAreaShop {
return;
}
if(group.removeMember(region)) {
plugin.message(sender, "groupdel-success", region.getName(), group.getName(), group.getMembers().size());
region.update();
plugin.message(sender, "groupdel-success", group.getName(), group.getMembers().size(), region);
} else {
plugin.message(sender, "groupdel-failed", region.getName(), group.getName());
plugin.message(sender, "groupdel-failed", group.getName(), region);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getGroupNames();
} else if(toComplete == 3) {
@@ -1,15 +1,13 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.RegionGroup;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class GroupinfoCommand extends CommandAreaShop {
public GroupinfoCommand(AreaShop plugin) {
@@ -31,7 +29,7 @@ public class GroupinfoCommand extends CommandAreaShop {
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.groupinfo")) {
plugin.message(sender, "groupinfo-noPermission");
return;
@@ -54,8 +52,8 @@ public class GroupinfoCommand extends CommandAreaShop {
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getGroupNames();
}
@@ -1,14 +1,12 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class GrouplistCommand extends CommandAreaShop {
public GrouplistCommand(AreaShop plugin) {
@@ -29,7 +27,7 @@ public class GrouplistCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.grouplist")) {
plugin.message(sender, "grouplist-noPermission");
return;
@@ -43,8 +41,8 @@ public class GrouplistCommand extends CommandAreaShop {
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
return new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
}
}
@@ -1,11 +1,6 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import org.bukkit.command.Command;
import nl.evolutioncoding.areashop.AreaShop;
import org.bukkit.command.CommandSender;
public class HelpCommand extends CommandAreaShop {
@@ -28,14 +23,7 @@ public class HelpCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
plugin.getCommandManager().showHelp(sender);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
return result;
}
}
@@ -0,0 +1,422 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.*;
public class InfoCommand extends CommandAreaShop {
public InfoCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop info";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.info")) {
return plugin.getLanguageManager().getLang("help-info");
}
return null;
}
/**
* Filter group of regions, join their names and printout the correct message
* @param sender The CommandSender to receive the message
* @param regions The regions
* @param filterGroup The group to filter to the regions with
* @param keySomeFound The key of the message to display when some regions are found
* @param keyNoneFound The key of the message to display when no regions are found
*/
private void displayMessage(CommandSender sender, Set<? extends GeneralRegion> regions, RegionGroup filterGroup, String keySomeFound, String keyNoneFound) {
if(filterGroup != null) {
Iterator<? extends GeneralRegion> it = regions.iterator();
while(it.hasNext()) {
GeneralRegion region = it.next();
if(!filterGroup.isMember(region)) {
it.remove();
}
}
}
if(regions.isEmpty()) {
plugin.message(sender, keyNoneFound);
} else {
plugin.message(sender, keySomeFound, StringUtils.join(regions.iterator(), ", "));
}
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.info")) {
plugin.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"));
if(groupFilters.contains(args[0].toLowerCase())) {
filterGroup = plugin.getFileManager().getGroup(args[2]);
if(filterGroup == null) {
plugin.message(sender, "info-noFiltergroup", args[2]);
return;
}
}
// All regions
if(args[1].equalsIgnoreCase("all")) {
Set<GeneralRegion> regions = new TreeSet<GeneralRegion>(plugin.getFileManager().getRents());
displayMessage(sender, regions, filterGroup, "info-all-rents", "info-all-noRents");
regions = new TreeSet<GeneralRegion>(plugin.getFileManager().getBuys());
displayMessage(sender, regions, filterGroup, "info-all-buys", "info-all-noBuys");
}
// Rented regions
else if(args[1].equalsIgnoreCase("rented")) {
Set<GeneralRegion> regions = new TreeSet<>();
for(RentRegion region : plugin.getFileManager().getRents()) {
if(region.isRented()) {
regions.add(region);
}
}
displayMessage(sender, regions, filterGroup, "info-rented", "info-noRented");
}
// Forrent regions
else if(args[1].equalsIgnoreCase("forrent")) {
Set<GeneralRegion> regions = new TreeSet<>();
for(RentRegion region : plugin.getFileManager().getRents()) {
if(!region.isRented()) {
regions.add(region);
}
}
displayMessage(sender, regions, filterGroup, "info-unrented", "info-noUnrented");
}
// Sold regions
else if(args[1].equalsIgnoreCase("sold")) {
Set<GeneralRegion> regions = new TreeSet<>();
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(region.isSold()) {
regions.add(region);
}
}
displayMessage(sender, regions, filterGroup, "info-sold", "info-noSold");
}
// Forsale regions
else if(args[1].equalsIgnoreCase("forsale")) {
Set<GeneralRegion> regions = new TreeSet<>();
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(!region.isSold()) {
regions.add(region);
}
}
displayMessage(sender, regions, filterGroup, "info-forsale", "info-noForsale");
}
// Player regions
else if(args[1].equalsIgnoreCase("player")) {
if(args.length > 2 && args[2] != null) {
// Rents
Set<GeneralRegion> regions = new TreeSet<>();
for(RentRegion region : plugin.getFileManager().getRents()) {
if(region.isRented() && region.getPlayerName().equalsIgnoreCase(args[2])) {
regions.add(region);
}
}
if(regions.isEmpty()) {
plugin.message(sender, "info-playerNoRents", args[2]);
} else {
plugin.message(sender, "info-playerRents", args[2], StringUtils.join(regions.iterator(), ", "));
}
// Buys
regions = new TreeSet<>();
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(region.isSold() && region.getPlayerName().equalsIgnoreCase(args[2])) {
regions.add(region);
}
}
if(regions.isEmpty()) {
plugin.message(sender, "info-playerNoBuys", args[2]);
} else {
plugin.message(sender, "info-playerBuys", args[2], StringUtils.join(regions.iterator(), ", "));
}
} else {
plugin.message(sender, "info-playerHelp");
}
}
// Region info
else if(args[1].equalsIgnoreCase("region")) {
if(args.length > 1) {
RentRegion rent = null;
BuyRegion buy = null;
if(args.length > 2) {
rent = plugin.getFileManager().getRent(args[2]);
buy = plugin.getFileManager().getBuy(args[2]);
} else {
if (sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
if(regions.get(0).isRentRegion()) {
rent = (RentRegion)regions.get(0);
} else if(regions.get(0).isBuyRegion()) {
buy = (BuyRegion)regions.get(0);
}
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
}
if(rent == null && buy == null) {
plugin.message(sender, "info-regionNotExisting", args[2]);
return;
}
if(rent != null) {
plugin.message(sender, "info-regionHeaderRent", rent);
if(rent.isRented()) {
plugin.messageNoPrefix(sender, "info-regionRented", rent);
plugin.messageNoPrefix(sender, "info-regionExtending", rent);
plugin.messageNoPrefix(sender, "info-regionMoneyBackRent", rent);
if(!rent.getFriendNames().isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionFriends", rent);
}
} else {
plugin.messageNoPrefix(sender, "info-regionCanBeRented", rent);
}
if(rent.getLandlordName() != null) {
plugin.messageNoPrefix(sender, "info-regionLandlord", rent);
}
if(rent.getMaxExtends() != -1) {
if(rent.getMaxExtends() == 0) {
plugin.messageNoPrefix(sender, "info-regionNoExtending", rent);
} else if(rent.isRented()) {
plugin.messageNoPrefix(sender, "info-regionExtendsLeft", rent);
} else {
plugin.messageNoPrefix(sender, "info-regionMaxExtends", rent);
}
}
if(rent.getMaxRentTime() != -1) {
plugin.messageNoPrefix(sender, "info-regionMaxRentTime", rent);
}
if(rent.getInactiveTimeUntilUnrent() != -1) {
plugin.messageNoPrefix(sender, "info-regionInactiveUnrent", rent);
}
if(sender.hasPermission("areashop.teleport") || sender.hasPermission("areashop.teleportall")) {
Location teleport = rent.getTeleportLocation();
if(teleport == null) {
if(rent.isRented()) {
plugin.messageNoPrefix(sender, "info-regionNoTeleport", rent, plugin.getLanguageManager().getLang("info-regionTeleportHint", rent));
} else {
plugin.messageNoPrefix(sender, "info-regionNoTeleport", rent, "");
}
} else {
plugin.messageNoPrefix(sender, "info-regionTeleportAt", rent, teleport.getWorld().getName(), teleport.getBlockX(), teleport.getBlockY(), teleport.getBlockZ(), (int)teleport.getPitch(), (int)teleport.getYaw());
}
}
List<String> signLocations = new ArrayList<>();
for(Location location : rent.getSignLocations()) {
signLocations.add(plugin.getLanguageManager().getLang("info-regionSignLocation", location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()));
}
if(!signLocations.isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
}
if(sender.hasPermission("areashop.groupinfo") && !rent.getGroupNames().isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(rent.getGroupNames()));
}
if(rent.isRestoreEnabled()) {
if(sender.hasPermission("areashop.setrestore")) {
plugin.messageNoPrefix(sender, "info-regionRestoringRent", rent, plugin.getLanguageManager().getLang("info-regionRestoringProfile", rent.getRestoreProfile()));
} else {
plugin.messageNoPrefix(sender, "info-regionRestoringRent", rent, "");
}
}
if(!rent.isRented()) {
if(rent.restrictedToRegion()) {
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionRent", rent);
} else if(rent.restrictedToWorld()) {
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldRent", rent);
}
}
plugin.messageNoPrefix(sender, "info-regionFooterRent", rent);
} else if(buy != null) {
plugin.message(sender, "info-regionHeaderBuy", buy);
if(buy.isSold()) {
if(buy.isInResellingMode()) {
plugin.messageNoPrefix(sender, "info-regionReselling", buy);
plugin.messageNoPrefix(sender, "info-regionReselPrice", buy);
} else {
plugin.messageNoPrefix(sender, "info-regionBought", buy);
}
plugin.messageNoPrefix(sender, "info-regionMoneyBackBuy", buy);
if(!buy.getFriendNames().isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionFriends", buy);
}
} else {
plugin.messageNoPrefix(sender, "info-regionCanBeBought", buy);
}
if(buy.getLandlord() != null) {
plugin.messageNoPrefix(sender, "info-regionLandlord", buy);
}
if(buy.getInactiveTimeUntilSell() != -1) {
plugin.messageNoPrefix(sender, "info-regionInactiveSell", buy);
}
if(sender.hasPermission("areashop.teleport") || sender.hasPermission("areashop.teleportall")) {
Location teleport = buy.getTeleportLocation();
if(teleport == null) {
if(buy.isSold()) {
plugin.messageNoPrefix(sender, "info-regionNoTeleport", buy, plugin.getLanguageManager().getLang("info-regionTeleportHint", buy));
} else {
plugin.messageNoPrefix(sender, "info-regionNoTeleport", buy, "");
}
} else {
plugin.messageNoPrefix(sender, "info-regionTeleportAt", buy, teleport.getWorld().getName(), teleport.getBlockX(), teleport.getBlockY(), teleport.getBlockZ(), (int)teleport.getPitch(), (int)teleport.getYaw());
}
}
List<String> signLocations = new ArrayList<>();
for(Location location : buy.getSignLocations()) {
signLocations.add(plugin.getLanguageManager().getLang("info-regionSignLocation", location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()));
}
if(!signLocations.isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionSigns", Utils.createCommaSeparatedList(signLocations));
}
if(sender.hasPermission("areashop.groupinfo") && !buy.getGroupNames().isEmpty()) {
plugin.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(buy.getGroupNames()));
}
if(buy.isRestoreEnabled()) {
if(sender.hasPermission("areashop.setrestore")) {
plugin.messageNoPrefix(sender, "info-regionRestoringBuy", buy, plugin.getLanguageManager().getLang("info-regionRestoringProfile", buy.getRestoreProfile()));
} else {
plugin.messageNoPrefix(sender, "info-regionRestoringBuy", buy, "");
}
}
if(!buy.isSold()) {
if(buy.restrictedToRegion()) {
plugin.messageNoPrefix(sender, "info-regionRestrictedRegionBuy", buy);
} else if(buy.restrictedToWorld()) {
plugin.messageNoPrefix(sender, "info-regionRestrictedWorldBuy", buy);
}
}
plugin.messageNoPrefix(sender, "info-regionFooterBuy", buy);
}
} else {
plugin.message(sender, "info-regionHelp");
}
}
// List of regions without a group
else if(args[1].equalsIgnoreCase("nogroup")) {
// Rental regions
Set<String> rents = new TreeSet<>(plugin.getFileManager().getRentNames());
for(RegionGroup group : plugin.getFileManager().getGroups()) {
rents.removeAll(group.getMembers());
}
String message = StringUtils.join(rents, ", ");
if(message.equals("")) {
plugin.message(sender, "info-nogroupNoRents");
} else {
plugin.message(sender, "info-nogroupRents", message);
}
// Buy regions
Set<String> buys = new TreeSet<>(plugin.getFileManager().getBuyNames());
for(RegionGroup group : plugin.getFileManager().getGroups()) {
buys.removeAll(group.getMembers());
}
message = StringUtils.join(buys, ", ");
if(message.equals("")) {
plugin.message(sender, "info-nogroupNoBuys");
} else {
plugin.message(sender, "info-nogroupBuys", message);
}
} else {
plugin.message(sender, "info-help");
}
} else {
plugin.message(sender, "info-help");
}
}
/**
* Create a comma-space separated list from a collection of strings
* @param list The collection with strings
* @return A comma-space separated list of the strings in the collection
*/
public String createCommaString(Collection<String> list) {
String result = "";
boolean first = true;
for(String part : list) {
if(first) {
result += part;
first = false;
} else {
result += ", " + part;
}
}
return result;
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(Arrays.asList("all", "rented", "forrent", "sold", "forsale", "player", "region", "nogroup"));
} 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(plugin.getFileManager().getBuyNames());
result.addAll(plugin.getFileManager().getRentNames());
}
}
return result;
}
}
@@ -0,0 +1,81 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class LinksignsCommand extends CommandAreaShop {
public LinksignsCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop linksigns";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.linksigns")) {
return plugin.getLanguageManager().getLang("help-linksigns");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.linksigns")) {
plugin.message(sender, "linksigns-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
if(plugin.getSignlinkerManager().isInSignLinkMode(player)) {
plugin.getSignlinkerManager().exitSignLinkMode(player);
} else {
// Get the profile
String profile = null;
if(args.length > 1) {
profile = args[1];
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
if(!profiles.contains(profile)) {
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles));
return;
}
}
plugin.getSignlinkerManager().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,115 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
public class MeCommand extends CommandAreaShop {
public MeCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop me";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.me")) {
return plugin.getLanguageManager().getLang("help-me");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.me")) {
plugin.message(sender, "me-noPermission");
return;
}
if(!(sender instanceof Player)) {
plugin.message(sender, "me-notAPlayer");
return;
}
Player player = (Player)sender;
// Get the regions owned by the player
Set<RentRegion> rentRegions = new HashSet<>();
for(RentRegion region : plugin.getFileManager().getRents()) {
if(region.isOwner(player)) {
rentRegions.add(region);
}
}
Set<BuyRegion> buyRegions = new HashSet<>();
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(region.isOwner(player)) {
buyRegions.add(region);
}
}
// Send messages
if(rentRegions.isEmpty()) {
plugin.message(player, "me-noRentRegions");
} else {
plugin.message(player, "me-rentRegions");
for(RentRegion region : rentRegions) {
plugin.messageNoPrefix(player, "me-rentLine", region);
}
}
if(buyRegions.isEmpty()) {
plugin.message(player, "me-noBuyRegions");
} else {
plugin.message(player, "me-buyRegions");
for(BuyRegion region : buyRegions) {
plugin.messageNoPrefix(player, "me-buyLine", region);
}
}
Set<GeneralRegion> friendRegions = new HashSet<>();
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
if(region.getFriends() != null && region.getFriends().contains(player.getUniqueId())) {
friendRegions.add(region);
}
}
if(friendRegions.isEmpty()) {
plugin.message(player, "me-noFriendRegions");
} else {
plugin.message(player, "me-friendRegions");
for(GeneralRegion region : friendRegions) {
plugin.messageNoPrefix(player, "me-friendLine", region);
}
}
}
}
@@ -1,11 +1,6 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import org.bukkit.command.Command;
import nl.evolutioncoding.areashop.AreaShop;
import org.bukkit.command.CommandSender;
public class ReloadCommand extends CommandAreaShop {
@@ -28,19 +23,12 @@ public class ReloadCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(sender.hasPermission("areashop.reload")) {
plugin.reload();
plugin.message(sender, "reload-reloaded");
// Reload the configuration files and update all region flags/signs
plugin.reload(sender);
} else {
plugin.message(sender, "reload-noPermission");
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
return result;
}
}
@@ -1,16 +1,14 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.RentRegion;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class RentCommand extends CommandAreaShop {
public RentCommand(AreaShop plugin) {
@@ -31,7 +29,11 @@ public class RentCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.rent")) {
plugin.message(sender, "rent-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
@@ -46,23 +48,20 @@ public class RentCommand extends CommandAreaShop {
}
} else {
// get the region by location
List<GeneralRegion> regions = plugin.getFileManager().getApplicalbeASRegions(player.getLocation());
if(regions.size() != 1) {
plugin.message(sender, "rent-help");
List<RentRegion> regions = Utils.getApplicableRentRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
} else {
if(!regions.get(0).isRentRegion()) {
plugin.message(sender, "rent-notRentable");
} else {
((RentRegion)regions.get(0)).rent(player);
}
plugin.saveConfig();
}
regions.get(0).rent(player);
}
}
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(RentRegion region : plugin.getFileManager().getRents()) {
if(!region.isRented()) {
@@ -0,0 +1,129 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class ResellCommand extends CommandAreaShop {
public ResellCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop resell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.resellall")) {
return plugin.getLanguageManager().getLang("help-resellAll");
} else if(target.hasPermission("areashop.resell")) {
return plugin.getLanguageManager().getLang("help-resell");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
plugin.message(sender, "resell-noPermissionOther");
return;
}
if(args.length <= 1) {
plugin.message(sender, "resell-help");
return;
}
double price;
try {
price = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
plugin.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.getApplicableBuyRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = plugin.getFileManager().getBuy(args[2]);
if(buy == null) {
plugin.message(sender, "resell-notRegistered", args[2]);
return;
}
}
if(buy == null) {
plugin.message(sender, "resell-noRegionFound");
return;
}
if(!buy.isSold()) {
plugin.message(sender, "resell-notBought", buy);
return;
}
if(sender.hasPermission("areashop.resellall")) {
buy.enableReselling(price);
buy.update();
plugin.message(sender, "resell-success", buy);
} else if(sender.hasPermission("areashop.resell") && sender instanceof Player) {
if(buy.isOwner((Player)sender)) {
buy.enableReselling(price);
buy.update();
plugin.message(sender, "resell-success", buy);
} else {
plugin.message(sender, "resell-noPermissionOther", buy);
}
} else {
plugin.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 : plugin.getFileManager().getBuys()) {
if(region.isSold() && !region.isInResellingMode()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -1,17 +1,15 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion.RegionEvent;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.Utils;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion.RegionEvent;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class SchematiceventCommand extends CommandAreaShop {
public SchematiceventCommand(AreaShop plugin) {
@@ -32,7 +30,7 @@ public class SchematiceventCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.schematicevents")) {
plugin.message(sender, "schemevent-noPermission");
return;
@@ -47,7 +45,10 @@ public class SchematiceventCommand extends CommandAreaShop {
plugin.message(sender, "schemevent-noRegion", args[1]);
return;
}
if(region.getRegion() == null) {
plugin.message(sender, "general-noRegion", region);
return;
}
RegionEvent event = null;
boolean exception = false;
try {
@@ -57,20 +58,21 @@ public class SchematiceventCommand extends CommandAreaShop {
}
// Check for a totally wrong event or a non matching event
if(exception) {
ArrayList<String> values = new ArrayList<String>();
ArrayList<String> values = new ArrayList<>();
for(RegionEvent value : RegionEvent.values()) {
values.add(value.getValue().toLowerCase());
}
plugin.message(sender, "schemevent-wrongEvent", args[2], Utils.createCommaSeparatedList(values));
plugin.message(sender, "schemevent-wrongEvent", args[2], Utils.createCommaSeparatedList(values), region);
return;
}
region.handleSchematicEvent(event);
plugin.message(sender, "schemevent-success", args[2], region.getName());
region.update();
plugin.message(sender, "schemevent-success", args[2], region);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
@@ -0,0 +1,99 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class SellCommand extends CommandAreaShop {
public SellCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop sell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.sell")) {
return plugin.getLanguageManager().getLang("help-sell");
} else if(target.hasPermission("areashop.sellown")) {
return plugin.getLanguageManager().getLang("help-sellOwn");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
plugin.message(sender, "sell-noPermission");
return;
}
BuyRegion buy;
if(args.length <= 1) {
if (sender instanceof Player) {
// get the region by location
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = plugin.getFileManager().getBuy(args[1]);
}
if(buy == null) {
plugin.message(sender, "sell-notRegistered");
return;
}
if(!buy.isSold()) {
plugin.message(sender, "sell-notBought", buy);
return;
}
buy.sell(true, sender);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(BuyRegion region : plugin.getFileManager().getBuys()) {
if(region.isSold()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,110 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class SetdurationCommand extends CommandAreaShop {
public SetdurationCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop setduration";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setduration")) {
return plugin.getLanguageManager().getLang("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)) {
plugin.message(sender, "setduration-noPermission");
return;
}
if(args.length < 3 || args[1] == null || args[2] == null) {
plugin.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.getApplicableRentRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
rent = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
rent = plugin.getFileManager().getRent(args[regionArgument]);
}
if(rent == null) {
plugin.message(sender, "setduration-notRegistered", args[regionArgument]);
return;
}
if(!sender.hasPermission("areashop.setduration") && !(sender instanceof Player && rent.isLandlord(((Player)sender).getUniqueId()))) {
plugin.message(sender, "setduration-noLandlord", rent);
return;
}
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
rent.setDuration(null);
rent.update();
plugin.message(sender, "setduration-successRemoved", rent);
return;
}
try {
Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
plugin.message(sender, "setduration-wrongAmount", args[1], rent);
return;
}
if(!Utils.checkTimeFormat(args[1]+" "+args[2])) {
plugin.message(sender, "setduration-wrongFormat", args[1]+" "+args[2], rent);
return;
}
rent.setDuration(args[1]+" "+args[2]);
rent.update();
plugin.message(sender, "setduration-success", rent);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getRentNames();
} else if(toComplete == 4) {
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"));
}
return result;
}
}
@@ -0,0 +1,92 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class SetlandlordCommand extends CommandAreaShop {
public SetlandlordCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop setlandlord";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setlandlord")) {
return plugin.getLanguageManager().getLang("help-setlandlord");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setlandlord")) {
plugin.message(sender, "setlandlord-noPermission");
return;
}
if(args.length < 2) {
plugin.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.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = plugin.getFileManager().getRegion(args[2]);
}
if(region == null) {
plugin.message(sender, "setlandlord-noRegion", args[2]);
return;
}
String playerName = player.getName();
if(playerName == null || playerName.isEmpty()) {
playerName = args[1];
}
region.setLandlord(player.getUniqueId(), playerName);
region.update();
plugin.message(sender, "setlandlord-success", playerName, region);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(Player player : Utils.getOnlinePlayers()) {
result.add(player.getName());
}
} else if(toComplete == 3) {
result.addAll(plugin.getFileManager().getRegionNames());
}
return result;
}
}
@@ -0,0 +1,145 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
public class SetownerCommand extends CommandAreaShop {
public SetownerCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop setowner";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
return plugin.getLanguageManager().getLang("help-setowner");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
plugin.message(sender, "setowner-noPermission");
return;
}
GeneralRegion region;
if(args.length < 2) {
plugin.message(sender, "setowner-help");
return;
}
if(args.length == 2) {
if (sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = plugin.getFileManager().getRegion(args[2]);
}
if(region == null) {
plugin.message(sender, "setowner-notRegistered");
return;
}
if(region.isRentRegion() && !sender.hasPermission("areashop.setownerrent")) {
plugin.message(sender, "setowner-noPermissionRent", region);
return;
}
if(region.isBuyRegion() && !sender.hasPermission("areashop.setownerbuy")) {
plugin.message(sender, "setowner-noPermissionBuy", region);
return;
}
UUID uuid = null;
@SuppressWarnings("deprecation")
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
if(player != null) {
uuid = player.getUniqueId();
}
if(uuid == null) {
plugin.message(sender, "setowner-noPlayer", args[1], region);
return;
}
if(region.isRentRegion()) {
RentRegion rent = (RentRegion)region;
if(rent.isRenter(uuid)) {
// extend
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(rent.getRentedUntil() + rent.getDuration());
rent.setRentedUntil(calendar.getTimeInMillis());
rent.setRenter(uuid);
rent.update();
plugin.message(sender, "setowner-succesRentExtend", region);
} else {
// change
Calendar calendar = Calendar.getInstance();
long current = calendar.getTimeInMillis();
if(rent.isRented()) {
current = rent.getRentedUntil();
}
calendar.setTimeInMillis(current + rent.getDuration());
rent.setRentedUntil(calendar.getTimeInMillis());
rent.setRenter(uuid);
rent.update();
plugin.message(sender, "setowner-succesRent", region);
}
}
if(region.isBuyRegion()) {
BuyRegion buy = (BuyRegion)region;
buy.setBuyer(uuid);
buy.update();
plugin.message(sender, "setowner-succesBuy", 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(plugin.getFileManager().getRegionNames());
}
return result;
}
}
@@ -0,0 +1,108 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class SetpriceCommand extends CommandAreaShop {
public SetpriceCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop setprice";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.setprice")) {
return plugin.getLanguageManager().getLang("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)) {
plugin.message(sender, "setprice-noPermission");
return;
}
if(args.length < 2 || args[1] == null) {
plugin.message(sender, "setprice-help");
return;
}
GeneralRegion region;
if(args.length < 3) {
if (sender instanceof Player) {
// get the region by location
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
region = plugin.getFileManager().getRegion(args[2]);
}
if(region == null) {
plugin.message(sender, "setprice-notRegistered", args[2]);
return;
}
if(!sender.hasPermission("areashop.setprice") && !(sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId()))) {
plugin.message(sender, "setprice-noLandlord", region);
return;
}
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
if(region.isRentRegion()) {
((RentRegion)region).removePrice();
} else if(region.isBuyRegion()) {
((BuyRegion)region).removePrice();
}
region.update();
plugin.message(sender, "setprice-successRemoved", region);
return;
}
double price;
try {
price = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
plugin.message(sender, "setprice-wrongPrice", args[1], region);
return;
}
if(region.isRentRegion()) {
((RentRegion)region).setPrice(price);
plugin.message(sender, "setprice-successRent", region);
} else if(region.isBuyRegion()) {
((BuyRegion)region).setPrice(price);
plugin.message(sender, "setprice-successBuy", region);
}
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 3) {
result = plugin.getFileManager().getRegionNames();
}
return result;
}
}
@@ -1,14 +1,12 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class SetrestoreCommand extends CommandAreaShop {
public SetrestoreCommand(AreaShop plugin) {
@@ -29,7 +27,7 @@ public class SetrestoreCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setrestore")) {
plugin.message(sender, "setrestore-noPermission");
return;
@@ -43,26 +41,29 @@ public class SetrestoreCommand extends CommandAreaShop {
plugin.message(sender, "setrestore-notRegistered", args[1]);
return;
}
String value = null;
if(args[2].equalsIgnoreCase("true") || args[2].equalsIgnoreCase("false") || args[2].equalsIgnoreCase("general")) {
value = args[2].toLowerCase();
} else {
plugin.message(sender, "setrestore-invalidSetting", args[2]);
return;
Boolean value = null;
if(args[2].equalsIgnoreCase("true")) {
value = true;
} else if(args[2].equalsIgnoreCase("false")) {
value = false;
}
region.setRestoreSetting(value);
if(args.length > 3) {
region.setRestoreProfile(args[3]);
plugin.message(sender, "setrestore-successProfile", region.getName(), value, args[3]);
} else {
plugin.message(sender, "setrestore-success", region.getName(), value);
String valueString = "general";
if(value != null) {
valueString = value+"";
}
region.save();
if(args.length > 3) {
region.setSchematicProfile(args[3]);
plugin.message(sender, "setrestore-successProfile", valueString, args[3], region);
} else {
plugin.message(sender, "setrestore-success", valueString, region);
}
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
List<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result = plugin.getFileManager().getRegionNames();
} else if(toComplete == 3) {
@@ -70,7 +71,7 @@ public class SetrestoreCommand extends CommandAreaShop {
result.add("false");
result.add("general");
} else if(toComplete == 4) {
result.addAll(plugin.config().getConfigurationSection("schematicProfiles").getKeys(false));
result.addAll(plugin.getConfig().getConfigurationSection("schematicProfiles").getKeys(false));
}
return result;
}
@@ -1,18 +1,16 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.BuyRegion;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import nl.evolutioncoding.AreaShop.regions.RentRegion;
import org.bukkit.command.Command;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.ArrayList;
import java.util.List;
public class SetteleportCommand extends CommandAreaShop {
@@ -36,27 +34,34 @@ public class SetteleportCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.setteleport") && !sender.hasPermission("areashop.setteleportall")) {
plugin.message(sender, "setteleport-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "onlyByPlayer");
return;
}
Player player = (Player) sender;
GeneralRegion region = null;
if(args.length <= 1) {
Player player = (Player)sender;
GeneralRegion region;
if(args.length < 2) {
// get the region by location
List<GeneralRegion> regions = plugin.getFileManager().getApplicalbeASRegions(((Player)sender).getLocation());
if(regions.size() != 1) {
plugin.message(sender, "setteleport-help");
List<GeneralRegion> regions = Utils.getAllApplicableRegions(((Player)sender).getLocation());
if(regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if(regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
region = regions.get(0);
}
}
} else {
region = plugin.getFileManager().getRegion(args[1]);
}
boolean owner = false;
boolean owner;
if(region == null) {
plugin.message(player, "setteleport-noRentOrBuy", args[1]);
@@ -68,30 +73,32 @@ public class SetteleportCommand extends CommandAreaShop {
owner = player.getUniqueId().equals(((BuyRegion)region).getBuyer());
}
if(!player.hasPermission("areashop.setteleport")) {
plugin.message(player, "setteleport-noPermission");
plugin.message(player, "setteleport-noPermission", region);
return;
} else if(!owner && !player.hasPermission("areashop.setteleportall")) {
plugin.message(player, "setteleport-noPermissionOther");
plugin.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.setTeleport(null);
plugin.message(player, "setteleport-reset", region.getName());
region.update();
plugin.message(player, "setteleport-reset", region);
return;
}
if(!wgRegion.contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()) && !player.hasPermission(" areashop.setteleportoutsideregion")) {
plugin.message(player, "setteleport-notInside", region.getName());
if(!player.hasPermission("areashop.setteleportoutsideregion") && (wgRegion == null || !wgRegion.contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
plugin.message(player, "setteleport-notInside", region);
return;
}
region.setTeleport(player.getLocation());
plugin.message(player, "setteleport-success", region.getName());
region.update();
plugin.message(player, "setteleport-success", region);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
@@ -0,0 +1,228 @@
package nl.evolutioncoding.areashop.commands;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import nl.evolutioncoding.areashop.regions.GeneralRegion.RegionEvent;
import nl.evolutioncoding.areashop.regions.RegionGroup;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.List;
public class StackCommand extends CommandAreaShop {
public StackCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop stack";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.stack")) {
return plugin.getLanguageManager().getLang("help-stack");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
// Check permission
if(!sender.hasPermission("areashop.stack")) {
plugin.message(sender, "stack-noPermission");
return;
}
// Only from ingame
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
final Player player = (Player)sender;
// Specify enough arguments
if(args.length < 5) {
plugin.message(sender, "stack-help");
return;
}
// Check amount
int tempAmount = -1;
try {
tempAmount = Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
// Incorrect number
}
if(tempAmount <= 0) {
plugin.message(player, "stack-wrongAmount", args[1]);
return;
}
// Check gap
int gap;
try {
gap = Integer.parseInt(args[2]);
} catch(NumberFormatException e) {
plugin.message(player, "stack-wrongGap", args[2]);
return;
}
// Check region type
if(!"rent".equalsIgnoreCase(args[4]) && !"buy".equalsIgnoreCase(args[4])) {
plugin.message(sender, "stack-help");
return;
}
// Get WorldEdit selection
final Selection selection = plugin.getWorldEdit().getSelection(player);
if(selection == null) {
plugin.message(player, "stack-noSelection");
return;
}
// Get or create group
RegionGroup group = null;
if(args.length > 5) {
group = plugin.getFileManager().getGroup(args[5]);
if(group == null) {
group = new RegionGroup(plugin, args[5]);
plugin.getFileManager().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(!(facing == BlockFace.NORTH || facing == BlockFace.EAST || facing == BlockFace.SOUTH || facing == BlockFace.WEST)) {
plugin.message(player, "stack-unclearDirection", facing.toString().toLowerCase().replace('_', '-'));
return;
}
final Location shift = new Location(selection.getWorld(), 0, 0, 0);
if(facing == BlockFace.SOUTH) {
shift.setZ(-selection.getLength() - gap);
} else if(facing == BlockFace.WEST) {
shift.setX(selection.getWidth() + gap);
} else if(facing == BlockFace.NORTH) {
shift.setZ(selection.getLength() + gap);
} else if(facing == BlockFace.EAST) {
shift.setX(-selection.getWidth() - gap);
}
AreaShop.debug(" calculated shift vector: " + shift + ", with facing=" + facing);
// Create regions and add them to AreaShop
final String namePrefix = 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;
String type;
if(rentRegions) {
type = "rent";
} else {
type = "buy";
}
String groupsMessage = "";
if(group != null) {
groupsMessage = plugin.getLanguageManager().getLang("stack-addToGroup", group.getName());
}
plugin.message(player, "stack-accepted", amount, type, gap, namePrefix, groupsMessage);
plugin.message(player, "stack-addStart", amount, regionsPerTick*20);
new BukkitRunnable() {
private int current = 0;
private RegionManager manager = AreaShop.getInstance().getWorldGuard().getRegionManager(selection.getWorld());
private int counter = 1;
@Override
public void run() {
for(int i=0; i<regionsPerTick; i++) {
if(current < amount) {
// Create the region name
String counterName = counter+"";
int minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
while(counterName.length() < minimumLength) {
counterName = "0"+counterName;
}
String regionName = namePrefix + counterName;
while(manager.getRegion(regionName) != null || AreaShop.getInstance().getFileManager().getRegion(regionName) != null) {
counter++;
counterName = counter+"";
minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
while(counterName.length() < minimumLength) {
counterName = "0"+counterName;
}
regionName = namePrefix + counterName;
}
// Add the region to WorldGuard (at startposition shifted by the number of this region times the blocks it should shift)
ProtectedCuboidRegion region = new ProtectedCuboidRegion(regionName,
new BlockVector(
selection.getMinimumPoint().getBlockX() + shift.getBlockX()*current,
selection.getMinimumPoint().getBlockY() + shift.getBlockY()*current,
selection.getMinimumPoint().getBlockZ() + shift.getBlockZ()*current
),
new BlockVector(
selection.getMaximumPoint().getBlockX() + shift.getBlockX()*current,
selection.getMaximumPoint().getBlockY() + shift.getBlockY()*current,
selection.getMaximumPoint().getBlockZ() + shift.getBlockZ()*current
)
);
manager.addRegion(region);
// Add the region to AreaShop
if(rentRegions) {
RentRegion rent = new RentRegion(plugin, region.getId(), selection.getWorld());
if(finalGroup != null) {
finalGroup.addMember(rent);
}
rent.runEventCommands(RegionEvent.CREATED, true);
plugin.getFileManager().addRent(rent);
rent.handleSchematicEvent(RegionEvent.CREATED);
rent.runEventCommands(RegionEvent.CREATED, false);
rent.update();
} else {
BuyRegion buy = new BuyRegion(plugin, region.getId(), selection.getWorld());
if(finalGroup != null) {
finalGroup.addMember(buy);
}
buy.runEventCommands(RegionEvent.CREATED, true);
plugin.getFileManager().addBuy(buy);
buy.handleSchematicEvent(RegionEvent.CREATED);
buy.runEventCommands(RegionEvent.CREATED, false);
buy.update();
}
current++;
}
}
if(current >= amount) {
if(player.isOnline()) {
plugin.message(player, "stack-addComplete");
}
this.cancel();
}
}
}.runTaskTimer(plugin, 1, 1);
}
@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(plugin.getFileManager().getGroupNames());
}
return result;
}
}
@@ -0,0 +1,118 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class StopresellCommand extends CommandAreaShop {
public StopresellCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop stopresell";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.stopresellall")) {
return plugin.getLanguageManager().getLang("help-stopResellAll");
} else if(target.hasPermission("areashop.stopresell")) {
return plugin.getLanguageManager().getLang("help-stopResell");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
plugin.message(sender, "stopresell-noPermissionOther");
return;
}
BuyRegion buy;
if(args.length <= 1) {
if (sender instanceof Player) {
// get the region by location
List<BuyRegion> regions = Utils.getApplicableBuyRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
buy = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
buy = plugin.getFileManager().getBuy(args[1]);
if(buy == null) {
plugin.message(sender, "stopresell-notRegistered", args[1]);
return;
}
}
if(buy == null) {
plugin.message(sender, "stopresell-noRegionFound");
return;
}
if(!buy.isInResellingMode()) {
plugin.message(sender, "stopresell-notResell", buy);
return;
}
if(sender.hasPermission("areashop.stopresellall")) {
buy.disableReselling();
buy.update();
plugin.message(sender, "stopresell-success", buy);
} else if(sender.hasPermission("areashop.stopresell") && sender instanceof Player) {
if(buy.isOwner((Player)sender)) {
buy.disableReselling();
buy.update();
plugin.message(sender, "stopresell-success", buy);
} else {
plugin.message(sender, "stopresell-noPermissionOther", buy);
}
} else {
plugin.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 : plugin.getFileManager().getBuys()) {
if(region.isSold() && region.isInResellingMode()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -1,15 +1,13 @@
package nl.evolutioncoding.AreaShop.commands;
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import nl.evolutioncoding.AreaShop.AreaShop;
import nl.evolutioncoding.AreaShop.regions.GeneralRegion;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class TeleportCommand extends CommandAreaShop {
public TeleportCommand(AreaShop plugin) {
@@ -32,7 +30,11 @@ public class TeleportCommand extends CommandAreaShop {
}
@Override
public void execute(CommandSender sender, Command command, String[] args) {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
plugin.message(sender, "teleport-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
@@ -56,8 +58,8 @@ public class TeleportCommand extends CommandAreaShop {
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start) {
ArrayList<String> result = new ArrayList<String>();
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
@@ -0,0 +1,91 @@
package nl.evolutioncoding.areashop.commands;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class UnrentCommand extends CommandAreaShop {
public UnrentCommand(AreaShop plugin) {
super(plugin);
}
@Override
public String getCommandStart() {
return "areashop unrent";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.unrent")) {
return plugin.getLanguageManager().getLang("help-unrent");
} else if(target.hasPermission("areashop.unrentown")) {
return plugin.getLanguageManager().getLang("help-unrentOwn");
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
plugin.message(sender, "unrent-noPermission");
return;
}
RentRegion rent;
if(args.length <= 1) {
if (sender instanceof Player) {
// get the region by location
List<RentRegion> regions = Utils.getApplicableRentRegions(((Player) sender).getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "cmd-moreRegionsAtLocation");
return;
} else {
rent = regions.get(0);
}
} else {
plugin.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}
} else {
rent = plugin.getFileManager().getRent(args[1]);
}
if(rent == null) {
plugin.message(sender, "unrent-notRegistered");
return;
}
if(!rent.isRented()) {
plugin.message(sender, "unrent-notRented", rent);
return;
}
rent.unRent(true, sender);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
for(RentRegion region : plugin.getFileManager().getRents()) {
if(region.isRented()) {
result.add(region.getName());
}
}
}
return result;
}
}
@@ -0,0 +1,53 @@
package nl.evolutioncoding.areashop.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CancellableAreaShopEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private String reason;
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* 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,18 @@
package nl.evolutioncoding.areashop.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class NotifyAreaShopEvent extends Event {
private static final HandlerList handlers = new HandlerList();
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -0,0 +1,40 @@
package nl.evolutioncoding.areashop.events.ask;
import nl.evolutioncoding.areashop.events.CancellableAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.entity.Player;
/**
* Broadcasted when a player tries to buy a region.
*/
public class BuyingRegionEvent extends CancellableAreaShopEvent {
private BuyRegion region;
private Player 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, Player player) {
this.region = region;
this.player = player;
}
/**
* Get the region that is about to be bought
* @return the region that is about to be bought
*/
public BuyRegion getRegion() {
return region;
}
/**
* Get the player that is trying to buy the region
* @return The player that is trying to buy the region
*/
public Player getPlayer() {
return player;
}
}
@@ -0,0 +1,51 @@
package nl.evolutioncoding.areashop.events.ask;
import nl.evolutioncoding.areashop.events.CancellableAreaShopEvent;
import nl.evolutioncoding.areashop.regions.RentRegion;
import org.bukkit.entity.Player;
/**
* Broadcasted when a player tries to rent a region
*/
public class RentingRegionEvent extends CancellableAreaShopEvent {
private RentRegion region;
private Player player;
private 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, Player player, boolean extending) {
this.region = region;
this.player = player;
this.extending = extending;
}
/**
* Get the region that is about to be rented
* @return the region that is about to be rented
*/
public RentRegion getRegion() {
return region;
}
/**
* Get the player that is trying to rent the region
* @return The player that is trying to rent the region
*/
public Player 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,40 @@
package nl.evolutioncoding.areashop.events.ask;
import nl.evolutioncoding.areashop.events.CancellableAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import org.bukkit.entity.Player;
/**
* Broadcasted when a player tries to resell a region
*/
public class ResellingRegionEvent extends CancellableAreaShopEvent {
private BuyRegion region;
private Player 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, Player player) {
this.region = region;
this.player = player;
}
/**
* Get the region that is about to be bought
* @return the region that is about to be bought
*/
public BuyRegion getRegion() {
return region;
}
/**
* Get the player that is trying to buy the region
* @return The player that is trying to buy the region
*/
public Player getBuyer() {
return player;
}
}
@@ -0,0 +1,28 @@
package nl.evolutioncoding.areashop.events.ask;
import nl.evolutioncoding.areashop.events.CancellableAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
/**
* Broadcasted when a region is about to get sold
*/
public class SellingRegionEvent extends CancellableAreaShopEvent {
private BuyRegion region;
/**
* Constructor
* @param region The region that is about to get sold
*/
public SellingRegionEvent(BuyRegion region) {
this.region = region;
}
/**
* Get the region that is about to be sold
* @return the region that is about to be sold
*/
public BuyRegion getRegion() {
return region;
}
}
@@ -0,0 +1,28 @@
package nl.evolutioncoding.areashop.events.ask;
import nl.evolutioncoding.areashop.events.CancellableAreaShopEvent;
import nl.evolutioncoding.areashop.regions.RentRegion;
/**
* Broadcasted when a region is about to be unrented
*/
public class UnrentingRegionEvent extends CancellableAreaShopEvent {
private RentRegion region;
/**
* Constructor
* @param region The region that is about to be unrented
*/
public UnrentingRegionEvent(RentRegion region) {
this.region = region;
}
/**
* Get the region that is about to be rented
* @return the region that is about to be rented
*/
public RentRegion getRegion() {
return region;
}
}
@@ -0,0 +1,28 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
/**
* Broadcasted when a region has been added to AreaShop
*/
public class AddedRegionEvent extends NotifyAreaShopEvent {
private GeneralRegion region;
/**
* Constructor
* @param region The region that has been added
*/
public AddedRegionEvent(GeneralRegion region) {
this.region = region;
}
/**
* Get the region that has been added
* @return the region that has been added
*/
public GeneralRegion getRegion() {
return region;
}
}
@@ -0,0 +1,28 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
/**
* Broadcasted when a region has been bought
*/
public class BoughtRegionEvent extends NotifyAreaShopEvent {
private BuyRegion region;
/**
* Constructor
* @param region The region that has been bought
*/
public BoughtRegionEvent(BuyRegion region) {
this.region = region;
}
/**
* Get the region that has been bought
* @return the region that has been bought
*/
public BuyRegion getRegion() {
return region;
}
}
@@ -0,0 +1,29 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
/**
* Broadcasted when the data of a region changes.
* Should be used for updating displays that use region data.
*/
public class RegionUpdateEvent extends NotifyAreaShopEvent {
private GeneralRegion region;
/**
* Contructor
* @param region The region that has been updated
*/
public RegionUpdateEvent(GeneralRegion region) {
this.region = region;
}
/**
* The region that has been updated
* @return The GeneralRegion that has been updated
*/
public GeneralRegion getRegion() {
return region;
}
}
@@ -0,0 +1,28 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
/**
* Broadcasted when a region has been removed from AreaShop
*/
public class RemovedRegionEvent extends NotifyAreaShopEvent {
private GeneralRegion region;
/**
* Constructor
* @param region The region that has been removed
*/
public RemovedRegionEvent(GeneralRegion region) {
this.region = region;
}
/**
* Get the region that has been removed
* @return the region that has been removed
*/
public GeneralRegion getRegion() {
return region;
}
}
@@ -0,0 +1,39 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.RentRegion;
/**
* Broadcasted when a region has been rented
*/
public class RentedRegionEvent extends NotifyAreaShopEvent {
private RentRegion region;
private boolean extended;
/**
* Constructor
* @param region The region that has been rented
* @param extended true if the region has been extended, false if this is the first time buying the region
*/
public RentedRegionEvent(RentRegion region, boolean extended) {
this.region = region;
this.extended = extended;
}
/**
* Get the region that has been rented
* @return the region that has been rented
*/
public RentRegion getRegion() {
return region;
}
/**
* Check if the region was extended or rented for the first time
* @return true if the region was extended, false when rented for the first time
*/
public boolean hasExtended() {
return extended;
}
}
@@ -0,0 +1,41 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import java.util.UUID;
/**
* Broadcasted when a region has been resold
*/
public class ResoldRegionEvent extends NotifyAreaShopEvent {
private BuyRegion region;
private UUID from;
/**
* Constructor
* @param region The region that has been resold
* @param from The player from who the region has been resold to the current owner
*/
public ResoldRegionEvent(BuyRegion region, UUID from) {
this.region = region;
this.from = from;
}
/**
* Get the region that has been bought
* @return the region that has been bought
*/
public BuyRegion getRegion() {
return region;
}
/**
* Get the player that the region has been bought from
* @return The UUID of the player that the region has been bought from
*/
public UUID getFromPlayer() {
return from;
}
}
@@ -0,0 +1,41 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.BuyRegion;
import java.util.UUID;
/**
* Broadcasted when a region is sold
*/
public class SoldRegionEvent extends NotifyAreaShopEvent {
private BuyRegion region;
private UUID oldBuyer;
/**
* Constructor
* @param region The region that has been sold
* @param oldBuyer The player for which the region has been sold
*/
public SoldRegionEvent(BuyRegion region, UUID oldBuyer) {
this.region = region;
this.oldBuyer = oldBuyer;
}
/**
* Get the region that has been sold
* @return the region that has been sold
*/
public BuyRegion getRegion() {
return region;
}
/**
* Get the player that the region is sold for
* @return The UUID of the player that the region is sold for
*/
public UUID getOldBuyer() {
return oldBuyer;
}
}
@@ -0,0 +1,41 @@
package nl.evolutioncoding.areashop.events.notify;
import nl.evolutioncoding.areashop.events.NotifyAreaShopEvent;
import nl.evolutioncoding.areashop.regions.RentRegion;
import java.util.UUID;
/**
* Broadcasted when a region has been unrented
*/
public class UnrentedRegionEvent extends NotifyAreaShopEvent {
private RentRegion region;
private UUID oldRenter;
/**
* Constructor
* @param region The region that has been unrented
* @param oldRenter The player that rented the region before it was unrented
*/
public UnrentedRegionEvent(RentRegion region, UUID oldRenter) {
this.region = region;
this.oldRenter = oldRenter;
}
/**
* Get the region that has been unrented
* @return the region that has been unrented
*/
public RentRegion getRegion() {
return region;
}
/**
* Get the player that the region was unrented for
* @return The UUID of the player that the region was unrented for
*/
public UUID getOldRenter() {
return oldRenter;
}
}
@@ -0,0 +1,70 @@
package nl.evolutioncoding.areashop.features;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.events.ask.*;
import nl.evolutioncoding.areashop.events.notify.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class DebugFeature extends Feature implements Listener {
public DebugFeature(AreaShop plugin) {
super(plugin);
}
@EventHandler
public void buyingRegion(BuyingRegionEvent event) {
AreaShop.debug("BuyingRegionEvent: " + event.getPlayer().getName() + " is trying to buy " + event.getRegion().getName());
}
@EventHandler
public void boughtRegion(BoughtRegionEvent event) {
AreaShop.debug("BoughtRegionEvent: " + event.getRegion().getPlayerName() + " bought " + event.getRegion().getName());
}
@EventHandler
public void sellingRegion(SellingRegionEvent event) {
AreaShop.debug("SellingRegionEvent: " + event.getRegion().getName() + " is trying to sell " + event.getRegion().getName());
}
@EventHandler
public void soldRegion(SoldRegionEvent event) {
AreaShop.debug("SoldRegionEvent: "+Utils.toName(event.getOldBuyer())+" sold "+event.getRegion().getName());
}
@EventHandler
public void resellingRegion(ResellingRegionEvent event) {
AreaShop.debug("ResellingRegionEvent: " + event.getRegion().getName() + " is trying to resell " + event.getRegion().getName());
}
@EventHandler
public void resoldRegion(ResoldRegionEvent event) {
AreaShop.debug("ResoldRegionEvent: "+Utils.toName(event.getFromPlayer())+" resold "+event.getRegion().getName()+" to "+event.getRegion().getPlayerName());
}
@EventHandler
public void rentingRegion(RentingRegionEvent event) {
AreaShop.debug("RentingRegionEvent: " + event.getPlayer().getName() + " is trying to rent " + event.getRegion().getName() + ", extending=" + event.isExtending());
}
@EventHandler
public void rentedRegion(RentedRegionEvent event) {
AreaShop.debug("RentedRegionEvent: " + event.getRegion().getPlayerName() + " rented " + event.getRegion().getName() + ", extending=" + event.hasExtended());
}
@EventHandler
public void unrentingRegion(UnrentingRegionEvent event) {
AreaShop.debug("UnrentingRegionEvent: " + event.getRegion().getPlayerName() + " is trying to unrent " + event.getRegion().getName());
}
@EventHandler
public void unrentedRegion(UnrentedRegionEvent event) {
AreaShop.debug("UnrentedRegionEvent: "+Utils.toName(event.getOldRenter())+" unrented "+event.getRegion().getName());
}
@EventHandler
public void regionUpdate(RegionUpdateEvent event) {
//AreaShop.debug("RegionUpdateEvent: " + event.getRegion().getName() + " updated");
}
}
@@ -0,0 +1,12 @@
package nl.evolutioncoding.areashop.features;
import nl.evolutioncoding.areashop.AreaShop;
public class Feature {
AreaShop plugin;
public Feature(AreaShop plugin) {
this.plugin = plugin;
}
}
@@ -0,0 +1,126 @@
package nl.evolutioncoding.areashop.features;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.Utils;
import nl.evolutioncoding.areashop.events.notify.RegionUpdateEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.Set;
public class SignDisplayFeature extends Feature implements Listener {
public SignDisplayFeature(AreaShop plugin) {
super(plugin);
}
@EventHandler
public void regionUpdate(RegionUpdateEvent event) {
updateSigns(event.getRegion());
}
/**
* Update the signs connected to this region
* @return true if the update was successful, otherwise false
*/
public boolean updateSigns(GeneralRegion region) {
if(region.isDeleted()) {
return false;
}
YamlConfiguration config = region.getConfig();
boolean result = true;
Set<String> signs = null;
if(config.getConfigurationSection("general.signs") != null) {
signs = config.getConfigurationSection("general.signs").getKeys(false);
}
if(signs == null) {
return true;
}
for(String sign : signs) {
Location location = Utils.configToLocation(config.getConfigurationSection("general.signs." + sign + ".location"));
if(location == null) {
AreaShop.debug("Sign location incorrect region=" + region.getName() + ", signKey=" + sign);
result = false;
} else {
// Get the profile set in the config
String profile = config.getString("general.signs." + sign + ".profile");
if(profile == null || profile.length() == 0) {
profile = region.getStringSetting("general.signProfile");
}
// Get the prefix
String prefix = "signProfiles." + profile + "." + region.getState().getValue().toLowerCase() + ".";
// Get the lines
String[] signLines = new String[4];
signLines[0] = plugin.getConfig().getString(prefix + "line1");
signLines[1] = plugin.getConfig().getString(prefix + "line2");
signLines[2] = plugin.getConfig().getString(prefix + "line3");
signLines[3] = plugin.getConfig().getString(prefix + "line4");
// Check if the sign should be present
Block block = location.getBlock();
if(!plugin.getConfig().isSet(prefix)
|| ((signLines[0] == null || signLines[0].length() == 0)
&& (signLines[1] == null || signLines[1].length() == 0)
&& (signLines[2] == null || signLines[2].length() == 0)
&& (signLines[3] == null || signLines[3].length() == 0))) {
block.setType(Material.AIR);
} else {
Sign signState = null;
if(block.getType() != Material.WALL_SIGN && block.getType() != Material.SIGN_POST) {
Material signType;
try {
signType = Material.valueOf(config.getString("general.signs." + sign + ".signType"));
} catch(NullPointerException | IllegalArgumentException e) {
signType = null;
}
if(signType != Material.WALL_SIGN && signType != Material.SIGN_POST) {
AreaShop.debug(" setting sign failed");
continue;
}
block.setType(signType);
signState = (Sign)block.getState();
org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData();
BlockFace signFace;
try {
signFace = BlockFace.valueOf(config.getString("general.signs." + sign + ".facing"));
} catch(NullPointerException | IllegalArgumentException e) {
signFace = null;
}
if(signFace != null) {
signData.setFacingDirection(signFace);
signState.setData(signData);
}
}
if(signState == null) {
signState = (Sign)block.getState();
}
org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData();
if(!config.isString("general.signs." + sign + ".signType")) {
region.setSetting("general.signs." + sign + ".signType", signState.getType().toString());
}
if(!config.isString("general.signs." + sign + ".facing")) {
region.setSetting("general.signs." + sign + ".facing", signData.getFacing().toString());
}
// Apply replacements and color and then set it on the sign
for(int i = 0; i < signLines.length; i++) {
if(signLines[i] == null) {
signState.setLine(i, "");
continue;
}
signLines[i] = region.applyAllReplacements(signLines[i]);
signLines[i] = Utils.applyColors(signLines[i]);
signState.setLine(i, signLines[i]);
}
signState.update();
}
}
}
return result;
}
}
@@ -0,0 +1,189 @@
package nl.evolutioncoding.areashop.features;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.evolutioncoding.areashop.AreaShop;
import nl.evolutioncoding.areashop.events.notify.RegionUpdateEvent;
import nl.evolutioncoding.areashop.regions.GeneralRegion;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.Set;
public class WorldGuardRegionFlagsFeature extends Feature implements Listener {
public WorldGuardRegionFlagsFeature(AreaShop plugin) {
super(plugin);
}
@EventHandler
public void regionUpdate(RegionUpdateEvent event) {
updateRegionFlags(event.getRegion());
}
/**
* Set the region flags/options to the values of a ConfigurationSection
* @param region The region to update the flags for
* @return true if the flags have been set correctly, otherwise false
*/
protected boolean updateRegionFlags(GeneralRegion region) {
boolean result = true;
ConfigurationSection flags = plugin.getConfig().getConfigurationSection("flagProfiles." + region.getStringSetting("general.flagProfile") + "." + region.getState().getValue());
if(flags == null) {
AreaShop.debug("Flags section is null for region " + region.getName());
return false;
}
Set<String> flagNames = flags.getKeys(false);
WorldGuardPlugin worldGuard = plugin.getWorldGuard();
// Get the region
ProtectedRegion wRegion = region.getRegion();
if(wRegion == null) {
AreaShop.debug("Region '" + region.getName() + "' does not exist, setting flags failed");
return false;
}
// Loop through all flags that are set in the config
for(String flagName : flagNames) {
String value = flags.getString(flagName);
value = region.applyAllReplacements(value);
// In the config normal Bukkit color codes are used, those only need to be translated on 5.X WorldGuard versions
if(plugin.getWorldGuard().getDescription().getVersion().startsWith("5.")) {
value = translateBukkitToWorldGuardColors(value);
}
if(flagName.equalsIgnoreCase("members")) {
plugin.getWorldGuardHandler().setMembers(wRegion, value);
//AreaShop.debug(" Flag " + flagName + " set: " + members.toUserFriendlyString());
} else if(flagName.equalsIgnoreCase("owners")) {
plugin.getWorldGuardHandler().setOwners(wRegion, value);
//AreaShop.debug(" Flag " + flagName + " set: " + owners.toUserFriendlyString());
} else if(flagName.equalsIgnoreCase("priority")) {
try {
int priority = Integer.parseInt(value);
wRegion.setPriority(priority);
//AreaShop.debug(" Flag " + flagName + " set: " + value);
} catch(NumberFormatException e) {
plugin.getLogger().warning("The value of flag " + flagName + " is not a number");
result = false;
}
} else if(flagName.equalsIgnoreCase("parent")) {
if(region.getWorld() == null || worldGuard.getRegionManager(region.getWorld()) == null) {
continue;
}
ProtectedRegion parentRegion = worldGuard.getRegionManager(region.getWorld()).getRegion(value);
if(parentRegion != null) {
try {
wRegion.setParent(parentRegion);
//AreaShop.debug(" Flag " + flagName + " set: " + value);
} catch(ProtectedRegion.CircularInheritanceException e) {
plugin.getLogger().warning("The parent set in the config is not correct (circular inheritance)");
}
} else {
plugin.getLogger().warning("The parent set in the config is not correct (region does not exist)");
}
} else {
// Parse all other normal flags (groups are also handled)
String flagSetting = null;
com.sk89q.worldguard.protection.flags.RegionGroup groupValue = null;
Flag<?> foundFlag = DefaultFlag.fuzzyMatchFlag(flagName);
if(foundFlag == null) {
plugin.getLogger().warning("Found wrong flag in flagProfiles section: " + flagName + ", check if that is the correct WorldGuard flag");
continue;
}
RegionGroupFlag groupFlag = foundFlag.getRegionGroupFlag();
if(value == null || value.isEmpty()) {
wRegion.setFlag(foundFlag, null);
if(groupFlag != null) {
wRegion.setFlag(groupFlag, null);
}
//AreaShop.debug(" Flag " + flagName + " reset (+ possible group of flag)");
} else {
if(groupFlag == null) {
flagSetting = value;
} else {
for(String part : value.split(" ")) {
if(part.startsWith("g:")) {
if(part.length() > 2) {
try {
groupValue = groupFlag.parseInput(worldGuard, null, part.substring(2));
} catch(InvalidFlagFormat e) {
plugin.getLogger().warning("Found wrong group value for flag " + flagName);
}
}
} else {
if(flagSetting == null) {
flagSetting = part;
} else {
flagSetting += " " + part;
}
}
}
}
if(flagSetting != null) {
try {
setFlag(wRegion, foundFlag, flagSetting);
//AreaShop.debug(" Flag " + flagName + " set: " + flagSetting);
} catch(InvalidFlagFormat e) {
plugin.getLogger().warning("Found wrong value for flag " + flagName);
}
}
if(groupValue != null) {
if(groupValue == groupFlag.getDefault()) {
wRegion.setFlag(groupFlag, null);
//AreaShop.debug(" Group of flag " + flagName + " set to default: " + groupValue);
} else {
wRegion.setFlag(groupFlag, groupValue);
//AreaShop.debug(" Group of flag " + flagName + " set: " + groupValue);
}
}
}
}
}
// Indicate that the regions needs to be saved
plugin.getFileManager().saveIsRequiredForRegionWorld(region.getWorldName());
return result;
}
/**
* Set a WorldGuard region flag
* @param region The WorldGuard region to set
* @param flag The flag to set
* @param value The value to set the flag to
* @throws InvalidFlagFormat When the value of the flag is wrong
*/
protected static <V> void setFlag(ProtectedRegion region, Flag<V> flag, String value) throws InvalidFlagFormat {
region.setFlag(flag, flag.parseInput(WorldGuardPlugin.inst(), null, value));
}
/**
* Translate the color codes you put in greeting/farewell messages to the weird color codes of WorldGuard
* @param message The message where the color codes should be translated (this message has bukkit color codes)
* @return The string with the WorldGuard color codes
*/
public String translateBukkitToWorldGuardColors(String message) {
String result = message;
result = result.replace("&c", "&r");
result = result.replace("&4", "&R");
result = result.replace("&e", "&y");
result = result.replace("&6", "&Y");
result = result.replace("&a", "&g");
result = result.replace("&2", "&G");
result = result.replace("&b", "&c");
result = result.replace("&3", "&C");
result = result.replace("&9", "&b");
result = result.replace("&1", "&B");
result = result.replace("&d", "&p");
result = result.replace("&5", "&P");
result = result.replace("&0", "&0");
result = result.replace("&8", "&1");
result = result.replace("&7", "&2");
result = result.replace("&f", "&w");
result = result.replace("&r", "&x");
return result;
}
}
Loaded 100 of 163 files, more files were not shown because too many files have changed in this diff. Show more