1
0
mirror of https://github.com/mcMMO-Dev/mcMMO.git synced 2026-02-18 09:43:00 +01:00

Compare commits

..

180 Commits

Author SHA1 Message Date
GJ
9b2f4b7bde Because the old beta broke all the things. 2013-05-16 16:23:12 -04:00
GJ
24e5147a2a This was never an issue. 2013-05-16 16:13:53 -04:00
T00thpick1
0423a7831d Those were right the first time... 2013-05-16 15:55:25 -04:00
T00thpick1
feea22b3a4 Correctly order 2013-05-16 15:52:49 -04:00
T00thpick1
7f40a9f284 Explicitely state columns wanted to account for altered tables 2013-05-16 15:50:19 -04:00
GJ
bc706109e0 Fix issue with tables without party names. 2013-05-16 13:37:22 -04:00
GJ
a25bddba5e Back to active development. 2013-05-16 10:55:13 -04:00
GJ
ab897724d3 Weekly beta! 2013-05-16 10:54:40 -04:00
GJ
a7861fc54b Move all miscellaneous Spout code to a single location. 2013-05-16 10:51:18 -04:00
GJ
936bec8ff5 Unused import. 2013-05-16 09:32:48 -04:00
GJ
01d10971a1 Calling things that many times is BAD. 2013-05-16 09:32:27 -04:00
T00thpick1
12e388a392 Null checks 2013-05-16 09:30:02 -04:00
T00thpick1
fb450671d6 Alternative SQL player loading 2013-05-16 09:29:59 -04:00
GJ
fca5f9ec98 We shouldn't need to do this. If issues arise, then there's a bug in
Bukkit that needs patching.
2013-05-16 09:23:35 -04:00
GJ
c9ae6436bd Because we forget things too often. 2013-05-16 08:41:57 -04:00
GJ
b6c4d2b4ad Fixed bug where Nether Quartz wasn't included in Smelting or item
sharing
2013-05-16 08:13:01 -04:00
GJ
27ab2f5b12 Update localization files. 2013-05-16 07:35:00 -04:00
T00thpick1
9b08062a58 Typo 2013-05-15 20:36:43 -04:00
T00thpick1
401bdfa9ac Reset ability modes safely 2013-05-15 20:35:30 -04:00
TfT_02
68d8d6dd30 Added permission node to bypass the fishing exploit prevention
Permission node: `mcmmo.bypass.kraken` false by default.
2013-05-15 23:35:17 +02:00
GJ
2a57d7007d Don't go through everything twice. Also, those were horrible variable
names.
2013-05-15 17:28:47 -04:00
GJ
fd675ac291 Changed Spout notification tiers to be stored in SpoutConfig instead of
AdvancedConfig. Also restructured some Spout stuff for easier
readability.
2013-05-15 17:08:43 -04:00
GJ
41f020bbb7 Cleaning up our listeners, as well as some Spout stuff. 2013-05-15 15:39:40 -04:00
GJ
00dee500e0 Caching options is bad, and so was that way of getting the menu key. 2013-05-15 15:28:05 -04:00
GJ
36bdb8a63e Fixed mcMMO overwritting Spout titles set by other plugins. 2013-05-15 15:14:47 -04:00
GJ
aa9eb0868c Add option to use scoreboards for power level display, similar to the
Spout titles. This will NOT override any existing plugin that uses the
overhead scoreboard slot.
2013-05-15 15:13:11 -04:00
T00thpick1
48aafa9834 Unused import 2013-05-15 14:27:31 -04:00
T00thpick1
78f53f294a Debris should drop normal drops 2013-05-15 13:02:21 -04:00
TfT_02
3158c7e3eb List /party itemshare and /party expshare in /party ?
Closes #913
2013-05-15 19:00:34 +02:00
GJ
47d27ebf31 Update changelog. 2013-05-15 09:29:54 -04:00
GJ
bc3773ae75 Because apparently you can have metadata and an empty list too.
Fixes #1080
2013-05-15 09:29:24 -04:00
GJ
d8ddd27d71 Calculate bonus XP based on initial arrow location, rather than final
shooter location.
2013-05-15 08:35:12 -04:00
GJ
8d5696507a Add bow force multiplier to Archery XP. 2013-05-15 01:20:12 -04:00
T00thpick1
9ec376a228 Unused import and update changelog 2013-05-15 00:53:01 -04:00
T00thpick1
a05a0da9fb Mob Spawner XP multiplier 2013-05-15 00:48:18 -04:00
T00thpick1
5029ad9d93 Apply Perks after cutoff 2013-05-14 23:54:54 -04:00
T00thpick1
1444be665c No reason to specify MyISAM 2013-05-14 23:54:52 -04:00
GJ
3dedb94bdc Add new Experience API functions and clarify some old ones. 2013-05-14 23:30:36 -04:00
T00thpick1
c0f6c15a80 Fix SQL Syntax 2013-05-14 23:28:45 -04:00
T00thpick1
00626a4893 Update changelog.txt 2013-05-14 23:03:26 -04:00
T00thpick1
b416a59bb7 Don't cache config options to prepare for eventual config reload support 2013-05-14 22:59:16 -04:00
GJ
bf96fb2214 Update changelog 2013-05-14 22:45:10 -04:00
GJ
2e79c8d770 Properly track infinite arrows. 2013-05-14 22:45:09 -04:00
T00thpick1
6c9d1c4953 Make SQL removes delete from all tables 2013-05-14 22:20:06 -04:00
T00thpick1
df8df192d3 Update Changelog 2013-05-14 19:57:18 -04:00
T00thpick1
e5f43462c8 Certain operations do not work with child skills 2013-05-14 19:31:40 -04:00
GJ
1867a3e040 If they aren't in a party, they shouldn't be in party chat mode. 2013-05-14 13:10:54 -04:00
GJ
6818f98de3 Feedback is good. 2013-05-14 13:10:07 -04:00
GJ
f910c76248 Conventions. 2013-05-14 12:46:45 -04:00
GJ
975cbf0bf8 The cache should be here, not in the manager. 2013-05-14 12:46:04 -04:00
GJ
f10b3cef01 Config option for escaping from the Kraken. 2013-05-14 12:43:02 -04:00
T00thpick1
ad39c94773 AbilityDeactivateEvent 2013-05-14 12:18:52 -04:00
T00thpick1
f189ab30e5 Default should be default 2013-05-14 11:32:57 -04:00
GJ
0ad18ee971 Fix some config formatting issues. 2013-05-14 11:32:22 -04:00
GJ
501f5de55a Fixing everything you guys broke while I was gone... 2013-05-14 11:28:50 -04:00
T00thpick1
0b18ae8ff2 Formatting and things 2013-05-13 22:28:42 -04:00
T00thpick1
de12970486 New api event 2013-05-13 22:28:39 -04:00
Glitchfinder
7550b99aaa Patching more NPEs involving invbalid players, plus mob health bars. 2013-05-13 18:46:19 -07:00
Glitchfinder
ed5a43966d Patching NPEs involving invalid player objects and player interactions. 2013-05-13 18:46:18 -07:00
Glitchfinder
95ea6703f1 Fixing an NPE involving invalid players chatting. 2013-05-13 18:46:17 -07:00
T00thpick1
55f9092aa6 Fireworks adjustment 2013-05-13 21:23:16 -04:00
Glitchfinder
5f50a46603 Setting the treasure config to only enforce data limits for blocks. 2013-05-13 20:22:09 -04:00
Paul J Thordarson
c5e6704530 Magic Hunter fix and optimization
There was a small bug in magic hunter, where it tried to apply an
enchantment level between 1 and the Enchantment.getMaxLevel(), however
it didn't take into account Enchantment.getStartLevel(), so when it
tried to apply an enchantment level below the start level, an
IllegalArgumentException was being thrown and the magic hunter event
wasn't happening.

Also, it's potentially inefficient to recalculate which enchantments
are possible for each ItemStack every time, so I added a HashMap to
cache the possibleEnchantments for each material type, then check this
cache instead of just looping to regenerate the list each time.
2013-05-13 20:22:08 -04:00
T00thpick1
8552192894 Only apply permissions when skill is enabled 2013-05-13 20:19:50 -04:00
NuclearW
0261d16140 Give no mcMMO xp for skeletons that spawn as a spider jokey pair from spawners. 2013-05-11 18:54:25 -04:00
NuclearW
2b414526e5 Unleash the Quacken! 2013-05-09 11:04:34 -04:00
NuclearW
c0b7eb526a Change Squid variables to Creature. 2013-05-09 11:00:28 -04:00
t00thpick1
7b7196a8c4 Potatoes shouldn't explode by default 2013-05-05 23:00:14 -03:00
t00thpick1
f648289035 Potato fixes 2013-05-05 22:58:04 -03:00
TfT_02
8a0b1d548d Add item weights for armor and tools in the default file 2013-05-05 11:32:10 +02:00
NuclearW
1f17d5d11e Move the comment section attached to the Kraken in advanced.yml
This is to fix a shortcoming in the autoupdate-config loader, which will attach related comments to nodes.
Issue: A nodes will get comments from another node of the same name, anywhere else in the config.
Solution: Move the comment to be attached to the "Kraken" node.

Long term: This can be a known bug and worked around by the team, or can be addressed more seriously by looking into changing how comments are applied to configs.  For now, this is a patch solution that should work fine.

Fixes #1043
2013-05-05 05:27:11 -04:00
TfT_02
18efd09421 Remove \' since it somehow breaks the name display
For some reason using \' will show the pets name as:
"<player-name>'s {1}"
2013-05-05 00:36:58 +02:00
TfT_02
18d3b30647 Add a missing space 2013-05-04 23:34:19 +02:00
GJ
7f0243b2df For Iaccidentally. 2013-05-03 18:16:42 -04:00
GJ
33610c8997 Whoops. 2013-05-03 16:15:34 -04:00
GJ
8e0a1f4f70 Summon the kraken at will! 2013-05-03 16:14:03 -04:00
GJ
b07cf6bdde It's now possible to run away from the Kraken. 2013-05-03 15:49:29 -04:00
GJ
7ed218ee7f Cleanup this task a bit. 2013-05-03 13:43:23 -04:00
GJ
3aedeea220 Remove client-side rain if the player kills the kraken. 2013-05-03 12:11:52 -04:00
GJ
4f9b7b2609 Because you might be legitimately fishing at 5 seconds. 2013-05-03 07:51:59 -04:00
GJ
09abab1b5d Kraken sounds can now be set to either player-only or global (default). 2013-05-03 07:51:58 -04:00
GJ
499713c8e7 Because autoclicking to shake is OK. 2013-05-03 07:51:57 -04:00
GJ
cb953a1619 Disable global chat spam from the kraken by setting the server message
to an empty string in the config.
2013-05-03 07:51:56 -04:00
TfT_02
3ab4938f3d Also need to locale these two strings
Closes #1019
2013-05-02 21:08:20 +02:00
TfT_02
f6e9fd9f3a Add more localisation 2013-05-02 21:02:12 +02:00
GJ
8dab75f3cb Can't use brackets in YAML. 2013-05-02 08:48:17 -04:00
GJ
b36096e54d Fixed bug where non-player arrows couldn't be deflected. 2013-05-02 08:23:18 -04:00
GJ
0574de4a29 Configure the Kraken! 2013-05-02 07:56:29 -04:00
GJ
6d6bc3de76 Trim player names to 16 chars when needed. 2013-05-02 07:16:07 -04:00
GJ
5c4c3cf59c The Kraken hates boats. 2013-05-01 22:50:12 -04:00
GJ
0033c8864e A dead kraken can't attack. 2013-05-01 22:17:48 -04:00
GJ
e7c749ee3a Added boosts to Fishing chance depending on conditions. Also, the
kraken, now with 100% more sound!
2013-05-01 21:57:42 -04:00
GJ
5c026be0cd Don't need those. 2013-05-01 21:19:29 -04:00
GJ
c465546871 Unleash the Kraken! 2013-05-01 21:17:59 -04:00
GJ
3322677d32 Added "Ice Fishing" ability to Fishing 2013-05-01 10:18:19 -04:00
GJ
76cf0ebb01 Only play ability effects if there's room above the player. 2013-05-01 08:59:45 -04:00
GJ
d34a0cca30 Fix issue with using /mcpurge, /mcremove, and /mmoupdate from the
console. These commands now default to OP, because frankly there are
much worse things someone can do with OP status than mess with the mcMMO
database.
2013-05-01 08:40:01 -04:00
GJ
a77a916fcc One more time... 2013-04-30 17:31:06 -04:00
GJ
e1ebb96545 Still need to remove from pending even if offline. 2013-04-30 15:47:19 -04:00
GJ
d85a6bec43 Don't create a task we'll possibly never run. 2013-04-30 15:19:41 -04:00
GJ
78eb7787e9 We don't need this any more. 2013-04-30 15:13:55 -04:00
GJ
b55ce30b2d Clean up our main class a bit more. Still not perfect, but it's getting
there.
2013-04-30 15:07:29 -04:00
GJ
14050cf096 Oops. 2013-04-30 14:24:31 -04:00
GJ
5930128b7f Add soft-depend on CombatTag so it loads before mcMMO, allowing us to
ensure the name check is ONLY run if CombatTag is installed.
2013-04-30 13:53:21 -04:00
GJ
08be78fa35 Avoid possible IllegalStateException if player has logged out before
this processes.
2013-04-30 10:02:28 -04:00
GJ
88f43d9a91 Add command to clear or change scoreboards. 2013-04-30 09:48:53 -04:00
GJ
6cbf960dea Use the right value here. 2013-04-30 08:24:16 -04:00
TfT_02
374d34f76d Fixed that for you 2013-04-30 14:20:16 +02:00
GJ
cc486c2dc7 Update the localization files. 2013-04-29 16:27:25 -04:00
GJ
724dce07a9 Back to regular development. 2013-04-29 15:59:56 -04:00
GJ
1486e2063b Beta time! 2013-04-29 15:59:35 -04:00
GJ
50c9649b23 mcMMO - Now with 100% more scoreboards!
mcMMO now allows for the use of scoreboards to display information in
several instances. By default, all scoreboards are enabled in the config,
and will only display for 10 seconds. After 10 seconds, the scoreboard
will go away and revert to the previously displayed scoreboard, if one
exists.

A global scoreboard now exists for tracking all player stats, and will be
displayed when /mctop is used. Your name will be highlighted in gold when
looking through the scoreboard. Additionally, the scoreboard will display
players in groups of 15, rather than groups of 10 like in chat.
Unfortunately, due to the limitations of scoreboards, the player's rank
will not be displayed in front of their name.

The scoreboard area is now also used for displaying data for /mcrank,
/inspect. and /mcstats. Due to the way scoreboards are handled, the power
level is not guarenteed to show up at any given location in the
scoreboard, but is instead displayed in gold so that it can be easily
found.

Lastly, the scoreboard area is also now used for displaying current data
on skills when the relevant /<skillname> command is used. The effects and
ability stats will still be shown in chat, but the current level, xp, and
remaining xp will be shown in the scoreboard.
2013-04-29 15:45:07 -04:00
GJ
339a54b0ac Replace SkillMonitorTask with 3 unique timers instead. This should greatly
optimize our tool and ability cooldown tracking and hopefully reduce
server load.
2013-04-29 15:33:55 -04:00
GJ
b97afb85a1 Only check names if CombatTag is enabled. 2013-04-29 00:29:38 -04:00
GJ
15da9d580b The previous CombatTag fix should take care of these. 2013-04-28 16:52:14 -04:00
GJ
62aed496cc Fix issue with CombatTag NPC errors. Fixes #1012
NOTE: Do NOT change the default NPC name for CombatTag in your config,
or this fix won't work.
2013-04-28 16:50:41 -04:00
GJ
fba131936a Fix issue with tab-completing /party commands. 2013-04-28 01:11:51 -04:00
t00thpick1
70601a4560 Debug code - Why you be in main branch 2013-04-28 01:08:07 -03:00
t00thpick1
83604ecb6d Syntax fixes 2013-04-27 14:18:10 -03:00
TfT_02
b912f7072c Actually use float experience 2013-04-26 17:28:18 +02:00
GJ
7e7e468408 Fix /mcrank showing everything as unranked... 2013-04-26 10:51:17 -04:00
T00thpick1
748c97f6c1 Expand AbilityAPI capabilities 2013-04-25 21:47:41 -04:00
GJ
a3aab57cf8 I am bad at SQL. 2013-04-25 20:08:27 -04:00
GJ
5548e26dd9 Fixed bug where players could remain in party chat after leaving or
being kicked from a party.
2013-04-25 19:52:25 -04:00
GJ
89d2f07c03 Because the block is null if they click air. 2013-04-25 19:36:34 -04:00
GJ
f42a28f34f Use defaults in case these are null. 2013-04-25 19:26:50 -04:00
TfT_02
bdc753f03c Also add the cancel feature for the Salvage Anvil 2013-04-25 23:40:21 +02:00
TfT_02
68a7b540c5 Ask a confirmation when a player tries to repair an enchanted item 2013-04-25 23:29:49 +02:00
GJ
b2dd820507 Clean up a few more things. 2013-04-25 09:27:48 -04:00
GJ
612308eb9a No reason to have those variables. 2013-04-25 09:20:03 -04:00
GJ
98dc7b853a Protect our managers. 2013-04-25 09:16:42 -04:00
GJ
a2fefd6fb6 Oops. 2013-04-25 07:48:14 -04:00
TfT_02
17a0382283 Changed experience storage from integers to floats
This will make sure no experience is lost when the server has high
skill modifiers configured, or when low amounts of experience are being
shared.
2013-04-25 07:42:38 -04:00
GJ
eea5784527 Abstract our database operations into a single class.
This allows the logic between SQL and Flatfile to remain more hidden in
most cases and makes the code easier to read.
2013-04-25 07:41:23 -04:00
GJ
1aff2cf9eb Cleaning out some crap from our PlayerListener. 2013-04-24 21:18:31 -04:00
GJ
4fc6349824 Move healthbar stuff to it own class. 2013-04-24 11:40:34 -04:00
GJ
7a3921eace Make these actually random. 2013-04-24 11:05:40 -04:00
GJ
e99599c377 Fixed Smelting returning ink sacs instead of Lapis when double-dropping.
Fixes #986
2013-04-24 07:08:24 -04:00
GJ
e1f6366a00 Don't make a new File every time. 2013-04-23 09:32:28 -04:00
GJ
182b01ac2f Redundant check is redundant 2013-04-23 09:10:22 -04:00
GJ
18f3914428 Use the path we already have. 2013-04-23 09:10:03 -04:00
GJ
bd0a045da3 No need to handle the load ourselves. 2013-04-23 09:00:42 -04:00
t00thpick1
9a4bed8c67 Already set to config default in constructor 2013-04-23 01:25:54 -03:00
t00thpick1
ae0cf692cd Use defaults when using defaults. 2013-04-23 01:22:01 -03:00
GJ
2ca7d139fe Fix NPEs relating combat checks and world changing. Fixes #976, #979 2013-04-22 23:19:26 -04:00
TfT_02
7e67505dfb Remove redundant ChimaeraWing check
Also indent the code
2013-04-21 21:50:08 +02:00
TfT_02
21100de85d Move the ChimaeraWing permission check and add feedback 2013-04-21 21:48:42 +02:00
TfT_02
d8f799f8b4 Add a few missing items to the Shareables list 2013-04-20 16:11:07 +02:00
TfT_02
cb03a98113 Add pickup sounds to cancelled PlayerPickupItemEvents
This will make the player aware that he has picked up an item.
2013-04-20 13:24:50 +02:00
GJ
4b36a11dda Make sure the target is online.
This ensures that the McMMOPlayer object *should* be valid.
2013-04-18 22:18:06 -04:00
GJ
8099490213 Minor DB tweaks. 2013-04-18 22:18:05 -04:00
GJ
6cb2843707 Remove a stupid line. 2013-04-18 22:18:05 -04:00
TfT_02
e831f0561a Changed Call of the Wild, newly summoned pet's will have a custom name
Closes #972
2013-04-18 23:04:27 +02:00
GJ
d57c253b19 Returns in finally are bad. 2013-04-18 11:28:07 -04:00
GJ
c8c68ea7d9 A little file cleanup. 2013-04-18 11:23:45 -04:00
GJ
150fe730bd No point in having a class & method for one line of code. 2013-04-18 09:19:48 -04:00
GJ
8af425d067 Make this a bit more sane. 2013-04-18 09:09:12 -04:00
GJ
c3845abd2a Clean up a bit, and make the /party itemshare command recognize the new
"misc" option
2013-04-18 08:11:47 -04:00
GJ
eba6820ec6 Clean this up a bit. 2013-04-18 07:51:53 -04:00
TfT_02
822e40bc1f Added a new Party item share category "Misc" which contains a list of configurable items. 2013-04-17 16:03:34 +02:00
TfT_02
3ffcaae122 Track items dropped by a player, prevent them from being party shared 2013-04-17 15:20:09 +02:00
GJ
42a30b4521 Fixed Fishing treasures always having the same enchants. 2013-04-17 07:47:43 -04:00
GJ
377ed9e8e5 Fix not being able to change party owners. 2013-04-17 07:07:54 -04:00
GJ
be76fe61d8 Fixed being unable to kick party members. 2013-04-17 07:05:28 -04:00
GJ
07ba7a8d9e Nerf fishing again... AGAIN 2013-04-16 23:48:36 -04:00
GJ
2be3e3b43c Changed Berserk to add items to inventory rather than denying pickup 2013-04-16 23:44:41 -04:00
GJ
49bf190895 Update changelog. 2013-04-16 07:00:39 -04:00
GJ
c9a53bdaca Fixed NPE when trying to tab-complete /mctop 2013-04-15 12:52:11 -04:00
GJ
3a76a111d3 Use the mob name when we have it. 2013-04-14 02:10:48 -04:00
TfT_02
e59c7ac34a Reduced the amount of info messages in the console when enabling/disabling 2013-04-13 21:53:00 +02:00
TfT_02
f05b9ae365 Use LinkedHashSet instead of List 2013-04-13 18:43:22 +02:00
GJ
c60e5a65d6 Fixed shake drops not working.
NOTE: You need to delete your treasures.yml and allow it to regenerate.
2013-04-13 11:34:38 -04:00
TfT_02
1b4eda713f Moar magical fixes!
This will automagically fix bugged players who have joined multiple
parties.
2013-04-13 01:17:07 +02:00
TfT_02
cb133ced80 No longer needed! 2013-04-13 01:16:17 +02:00
TfT_02
062a3028f4 This makes it easier to read 2013-04-13 01:11:26 +02:00
TfT_02
682c2631f0 Fixed bug where players were able to join the same party multiple times
This change should automagically fix broken parties which have multiple
instances of the same player in it.

This will not fix bugged players who have joined multiple parties.
2013-04-13 00:41:36 +02:00
NuclearW
faecb9a439 Fix players not having ptp.send by default. 2013-04-12 18:25:52 -04:00
GJ
5dc40f3c03 Nerf fishing... again. 2013-04-12 17:48:04 -04:00
GJ
569e87847f Fixed fishing chance display values. 2013-04-12 10:25:00 -04:00
GJ
b448315f20 And now, back to your regularly scheduled development. 2013-04-11 23:55:13 -04:00
124 changed files with 5724 additions and 3230 deletions

View File

@@ -6,22 +6,58 @@ Key:
= Fix
! Change
- Removal
Version 1.4.06-dev
+ Added "Ice Fishing" ability to Fishing
+ Added global scoreboards to track skill rankings (display using /mctop)
+ Added per-player scoreboard displays for the /inspect, /mcrank, /mcstats, and /<skillname> commands
+ Added tab-complete support for all commands
+ Added ability to configure drops from Shake in treasures.yml
+ Added "Master Angler" ability to Fishing.
+ Added health display for mobs during combat.
+ Added new API method to McMMOPlayerLevelUpEvent to set levels gained
+ Added new permission node for /ptp; mcmmo.commands.ptp.send (enabled by default)
+ Added configurable cooldown and warmup times when using /ptp
+ Added a new Party item share category "Misc" which contains a list of configurable items. (By default all tools and armor)
+ Added fishing exploit prevention
+ Added permission node to bypass the fishing exploit prevention
+ Added boosts to Fishing chance depending on conditions
+ Added McMMOAbilityActivateEvent and McMMOAbilityDeactivateEvent
+ Added config option to toggle the size of fireworks
+ Added config option to multiply xp gains from mob spawner mobs
+ Added multiplier to Archery XP based on bow force
+ Added information about /party itemshare and /party expshare to the party help page
+ Added option to use scoreboards for power level display instead of Spout.
= Fixed bug where custom Spout titles were overwritten by mcMMO.
= Fixed bug where Nether Quartz wasn't included in Smelting or item sharing
= Fixed bug where players were able to join the same party multiple times
= Fixed displaying partial names when trying to use /ptp
= Fixed wolves from Call of the Wild only having 8 health
= Fixed bug where /party chat was not working
= Fixed bug where experience commands were adding levels to all skills when they shouldn't
= Fixed mcmmo.commands.ptp.send not being set by default
= Fixed NPE when trying to tab-complete /mctop
= Fixed Fishing treasures always having the same enchants
= Fixed Smelting returning ink sacs instead of Lapis when double-dropping
= Fixed bug where players could remain in party chat after leaving or being kicked from a party.
= Fixed bug where non-player arrows couldn't be deflected.
= Fixed experience being applied even when the permission for a skill was denied
= Fixed possible item duplication bug with infinity bows
= Fixed bug with removing players from mySQL database
= Fixed bug with empty metadata lists and Smelting
= Fixed bug where Blast Mining would drop wrong items
! Changed Spout notification tiers to be stored in SpoutConfig instead of AdvancedConfig
! Changed Berserk to add items to inventory rather than denying pickup
! Changed Call of the Wild, newly summoned pet's will have a custom name. (added permission node to disable this)
! Changed Chimaera Wing's recipe result to use the ingredient Material
! Changed Repair to ask a confirmation of the player when he tries to repair an enchanted item
! Players will no longer pickup items to their hotbar while using Unarmed
! ExperienceAPI methods will now throw InvalidSkillException if the skill name passed in is invalid.
! Changed default value for recently-hurt cooldown between teleports, this is also fully configurable now
! Changed the amount of info messages in the console when enabling/disabling, enable Verbose_Logging to enable them again
! Items dropped by players are now being tracked and are not being shared with party members
! Optimized tracking of tool & ability cooldowns.
! Updated the localization files
Version 1.4.05
+ Added option to allow refreshing of chunks after block-breaking abilities. (Disabled by default)

View File

@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>1.4.06-beta1</version>
<version>1.4.06-beta4</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<issueManagement>

View File

@@ -48,4 +48,36 @@ public final class AbilityAPI {
return false;
}
public static void resetCooldowns(Player player) {
UserManager.getPlayer(player).getProfile().resetCooldowns();
}
public static void setBerserkCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.BERSERK, cooldown);
}
public static void setGigaDrillBreakerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.GIGA_DRILL_BREAKER, cooldown);
}
public static void setGreenTerraCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.GREEN_TERRA, cooldown);
}
public static void setSerratedStrikesCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.SERRATED_STRIKES, cooldown);
}
public static void setSkullSplitterCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.SKULL_SPLITTER, cooldown);
}
public static void setSuperBreakerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.SUPER_BREAKER, cooldown);
}
public static void setTreeFellerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).getProfile().setSkillDATS(AbilityType.TREE_FELLER, cooldown);
}
}

View File

@@ -175,6 +175,7 @@ public final class ExperienceAPI {
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXP(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
@@ -183,6 +184,10 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return UserManager.getPlayer(player).getProfile().getSkillXpLevel(skill);
}
@@ -197,6 +202,7 @@ public final class ExperienceAPI {
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXP(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
@@ -205,32 +211,41 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return getOfflineProfile(playerName).getSkillXpLevel(skill);
}
/**
* Get the amount of XP left before leveling up.
* Get the raw amount of XP a player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param player The player to get the XP amount for
* @param skillType The skill to get the XP amount for
* @return the amount of XP left before leveling up a specifc skill
* @param player The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXPToNextLevel(Player player, String skillType) {
public static float getXPRaw(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getXpToLevel(skill);
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return UserManager.getPlayer(player).getProfile().getSkillXpLevelRaw(skill);
}
/**
* Get the amount of XP an offline player has left before leveling up.
* Get the raw amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
@@ -240,6 +255,60 @@ public final class ExperienceAPI {
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getOfflineXPRaw(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return getOfflineProfile(playerName).getSkillXpLevelRaw(skill);
}
/**
* Get the total amount of XP needed to reach the next level.
* </br>
* This function is designed for API usage.
*
* @param player The player to get the XP amount for
* @param skillType The skill to get the XP amount for
* @return the total amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXPToNextLevel(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return UserManager.getPlayer(player).getProfile().getXpToLevel(skill);
}
/**
* Get the total amount of XP an offline player needs to reach the next level.
* </br>
* This function is designed for API usage.
*
* @param playerName The player to get XP for
* @param skillType The skill to get XP for
* @return the total amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXPToNextLevel(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
@@ -248,9 +317,70 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
return getOfflineProfile(playerName).getXpToLevel(skill);
}
/**
* Get the amount of XP remaining until the next level.
* </br>
* This function is designed for API usage.
*
* @param player The player to get the XP amount for
* @param skillType The skill to get the XP amount for
* @return the amount of XP remaining until the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXPRemaining(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
return profile.getXpToLevel(skill) - profile.getSkillXpLevel(skill);
}
/**
* Get the amount of XP an offline player has left before leveling up.
* </br>
* This function is designed for API usage.
*
* @param playerName The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXPRemaining(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
PlayerProfile profile = getOfflineProfile(playerName);
return profile.getXpToLevel(skill) - profile.getSkillXpLevel(skill);
}
/**
* Add levels to a skill.
* </br>
@@ -471,6 +601,7 @@ public final class ExperienceAPI {
* @param newValue The value to set the XP to
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void setXP(Player player, String skillType, int newValue) {
SkillType skill = SkillType.getSkill(skillType);
@@ -479,6 +610,10 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
UserManager.getPlayer(player).getProfile().setSkillXpLevel(skill, newValue);
}
@@ -493,6 +628,7 @@ public final class ExperienceAPI {
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void setXPOffline(String playerName, String skillType, int newValue) {
SkillType skill = SkillType.getSkill(skillType);
@@ -501,6 +637,10 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
getOfflineProfile(playerName).setSkillXpLevel(skill, newValue);
}
@@ -514,6 +654,7 @@ public final class ExperienceAPI {
* @param xp The amount of XP to remove
*
* @throws InvalidSkillException if the given skill is not valid
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void removeXP(Player player, String skillType, int xp) {
SkillType skill = SkillType.getSkill(skillType);
@@ -522,6 +663,10 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
UserManager.getPlayer(player).getProfile().removeXp(skill, xp);
}
@@ -536,6 +681,7 @@ public final class ExperienceAPI {
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void removeXPOffline(String playerName, String skillType, int xp) {
SkillType skill = SkillType.getSkill(skillType);
@@ -544,6 +690,10 @@ public final class ExperienceAPI {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
throw new UnsupportedOperationException("Child skills do not have XP");
}
getOfflineProfile(playerName).removeXp(skill, xp);
}

View File

@@ -1,10 +1,13 @@
package com.gmail.nossr50.api;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.UserManager;
@@ -127,7 +130,26 @@ public final class PartyAPI {
* @param player The player to check
* @return all the players in the player's party
*/
@Deprecated
public static List<OfflinePlayer> getOnlineAndOfflineMembers(Player player) {
List<OfflinePlayer> members = new ArrayList<OfflinePlayer>();
for (String memberName : PartyManager.getAllMembers(player)) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberName);
members.add(member);
}
return members;
}
/**
* Get a list of all player names in this player's party.
* </br>
* This function is designed for API usage.
*
* @param player The player to check
* @return all the player names in the player's party
*/
public static LinkedHashSet<String> getMembers(Player player) {
return PartyManager.getAllMembers(player);
}

View File

@@ -0,0 +1,65 @@
package com.gmail.nossr50.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.google.common.collect.ImmutableList;
public class KrakenCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
case 0:
if (CommandUtils.noConsoleUsage(sender)) {
return true;
}
if (!Permissions.kraken(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
UserManager.getPlayer(sender.getName()).getFishingManager().unleashTheKraken();
return true;
case 1:
if (!Permissions.krakenOthers(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
return true;
}
mcMMOPlayer.getFishingManager().unleashTheKraken();
return true;
default:
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
Set<String> playerNames = UserManager.getPlayers().keySet();
return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
default:
return ImmutableList.of();
}
}
}

View File

@@ -1,17 +1,17 @@
package com.gmail.nossr50.commands;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.getspout.spoutapi.player.SpoutPlayer;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.commands.party.PartySubcommandType;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.spout.SpoutUtils;
public class McmmoCommand implements CommandExecutor {
@Override
@@ -28,13 +28,13 @@ public class McmmoCommand implements CommandExecutor {
sender.sendMessage(mcSplit);
if (Config.getInstance().getDonateMessageEnabled()) {
if (mcMMO.spoutEnabled && sender instanceof SpoutPlayer) {
SpoutPlayer spoutPlayer = (SpoutPlayer) sender;
spoutPlayer.sendNotification(LocaleLoader.getString("Spout.Donate"), ChatColor.GREEN + "gjmcferrin@gmail.com", Material.DIAMOND);
if (mcMMO.isSpoutEnabled() && sender instanceof Player) {
SpoutUtils.sendDonationNotification((Player) sender);
}
else {
sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "gjmcferrin@gmail.com" + ChatColor.GOLD + " Paypal");
}
sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "gjmcferrin@gmail.com" + ChatColor.GOLD + " Paypal");
}
sender.sendMessage(LocaleLoader.getString("MOTD.Version", mcMMO.p.getDescription().getVersion()));

View File

@@ -23,7 +23,6 @@ public class McrefreshCommand extends ToggleCommand {
mcMMOPlayer.resetToolPrepMode();
mcMMOPlayer.resetAbilityMode();
player.setCanPickupItems(true);
player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
}

View File

@@ -0,0 +1,141 @@
package com.gmail.nossr50.commands;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
public class McscoreboardCommand implements TabExecutor {
private static final List<String> SCOREBOARD_TYPES = ImmutableList.of("clear", "rank", "stats", "top");
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (CommandUtils.noConsoleUsage(sender)) {
return true;
}
Player player = (Player) sender;
switch (args.length) {
case 0:
clearScoreboard(player);
return true;
case 1:
if (args[0].equalsIgnoreCase("clear")) {
clearScoreboard(player);
}
else if (args[0].equalsIgnoreCase("rank")) {
if (!Config.getInstance().getMcrankScoreboardEnabled()) {
sender.sendMessage("This scoreboard is not enabled."); //TODO: Localize
return true;
}
ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerRankScoreboard(player);
}
else if (args[0].equalsIgnoreCase("stats")) {
if (!Config.getInstance().getMcstatsScoreboardsEnabled()) {
sender.sendMessage("This scoreboard is not enabled."); //TODO: Localize
return true;
}
ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerStatsScoreboard(UserManager.getPlayer(player));
}
else if (args[0].equalsIgnoreCase("top")) {
if (!Config.getInstance().getMctopScoreboardEnabled()) {
sender.sendMessage("This scoreboard is not enabled."); //TODO: Localize
return true;
}
ScoreboardManager.enableGlobalStatsScoreboard(player, "all", 1);
}
else {
return false;
}
return true;
case 2:
if (!args[0].equalsIgnoreCase("top")) {
return false;
}
if (!Config.getInstance().getMctopScoreboardEnabled()) {
sender.sendMessage("This scoreboard is not enabled."); //TODO: Localize
return true;
}
if (StringUtils.isInt(args[1])) {
ScoreboardManager.enableGlobalStatsScoreboard(player, "all", Math.abs(Integer.parseInt(args[1])));
return true;
}
if (CommandUtils.isInvalidSkill(sender, args[1])) {
return true;
}
ScoreboardManager.enableGlobalStatsScoreboard(player, args[1], 1);
return true;
case 3:
if (!args[0].equalsIgnoreCase("top")) {
return false;
}
if (!Config.getInstance().getMctopScoreboardEnabled()) {
sender.sendMessage("This scoreboard is not enabled."); //TODO: Localize
return true;
}
if (CommandUtils.isInvalidSkill(sender, args[1])) {
return true;
}
if (CommandUtils.isInvalidInteger(sender, args[2])) {
return true;
}
ScoreboardManager.enableGlobalStatsScoreboard(player, args[1], Math.abs(Integer.parseInt(args[2])));
return true;
default:
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[0], SCOREBOARD_TYPES, new ArrayList<String>(SCOREBOARD_TYPES.size()));
case 2:
if (args[0].equalsIgnoreCase("top")) {
return StringUtil.copyPartialMatches(args[1], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
}
// Fallthrough
default:
return ImmutableList.of();
}
}
private void clearScoreboard(Player player) {
player.setScoreboard(mcMMO.p.getServer().getScoreboardManager().getMainScoreboard());
player.sendMessage("Your scoreboard has been cleared!"); //TODO: Locale
}
}

View File

@@ -6,37 +6,21 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.LeaderboardManager;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.google.common.collect.ImmutableList;
public class McpurgeCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!Permissions.mcpurge(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
switch (args.length) {
case 0:
if (Config.getInstance().getUseMySQL()) {
DatabaseManager.purgePowerlessSQL();
mcMMO.getDatabaseManager().purgePowerlessUsers();
if (Config.getInstance().getOldUsersCutoff() != -1) {
DatabaseManager.purgeOldSQL();
}
}
else {
LeaderboardManager.purgePowerlessFlatfile();
if (Config.getInstance().getOldUsersCutoff() != -1) {
LeaderboardManager.purgeOldFlatfile();
}
if (Config.getInstance().getOldUsersCutoff() != -1) {
mcMMO.getDatabaseManager().purgeOldUsers();
}
sender.sendMessage(LocaleLoader.getString("Commands.mcpurge.Success"));

View File

@@ -9,13 +9,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.LeaderboardManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
@@ -24,31 +20,17 @@ import com.google.common.collect.ImmutableList;
public class McremoveCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!Permissions.mcremove(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
switch (args.length) {
case 1:
if (UserManager.getPlayer(args[0]) == null && CommandUtils.unloadedProfile(sender, new PlayerProfile(args[0], false))) {
return true;
}
/* MySQL */
if (Config.getInstance().getUseMySQL()) {
String tablePrefix = Config.getInstance().getMySQLTablePrefix();
if (DatabaseManager.update("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.user = '" + args[0] + "'") != 0) {
Misc.profileCleanup(args[0]);
sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
}
if (mcMMO.getDatabaseManager().removeUser(args[0])) {
sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
}
else {
if (LeaderboardManager.removeFlatFileUser(args[0])) {
Misc.profileCleanup(args[0]);
sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
}
sender.sendMessage(args[0] + " could not be removed from the database."); // Pretty sure this should NEVER happen.
}
return true;

View File

@@ -11,7 +11,6 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.database.SQLConversionTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.google.common.collect.ImmutableList;
@@ -19,11 +18,6 @@ import com.google.common.collect.ImmutableList;
public class MmoupdateCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!Permissions.mmoupdate(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
if (!Config.getInstance().getUseMySQL()) {
sender.sendMessage("SQL Mode is not enabled."); // TODO: Localize
return true;

View File

@@ -4,7 +4,6 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
@@ -17,7 +16,7 @@ public class PartyChangeOwnerCommand implements CommandExecutor {
case 2:
Party playerParty = UserManager.getPlayer(sender.getName()).getParty();
if (!playerParty.getMembers().contains(mcMMO.p.getServer().getOfflinePlayer(args[1]))) {
if (!playerParty.getMembers().contains(args[1])) {
sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));
return true;
}

View File

@@ -28,7 +28,7 @@ public class PartyCommand implements TabExecutor {
private static final List<String> PARTY_SUBCOMMANDS;
private static final List<String> EXPSHARE_COMPLETIONS = ImmutableList.of("none", "equal");
private static final List<String> ITEMSHARE_COMPLETIONS = ImmutableList.of("none", "equal", "random", "loot", "mining", "herbalism", "woodcutting");
private static final List<String> ITEMSHARE_COMPLETIONS = ImmutableList.of("none", "equal", "random", "loot", "mining", "herbalism", "woodcutting", "misc");
static {
ArrayList<String> subcommands = new ArrayList<String>();
@@ -171,7 +171,7 @@ public class PartyCommand implements TabExecutor {
return ImmutableList.of();
}
switch (PartySubcommandType.valueOf(args[0].toUpperCase())) {
switch (subcommand) {
case JOIN:
case INVITE:
case KICK:
@@ -228,7 +228,7 @@ public class PartyCommand implements TabExecutor {
}
private boolean isItemShareCategory(String category) {
return category.equalsIgnoreCase("loot") || category.equalsIgnoreCase("mining") || category.equalsIgnoreCase("herbalism") || category.equalsIgnoreCase("woodcutting");
return category.equalsIgnoreCase("loot") || category.equalsIgnoreCase("mining") || category.equalsIgnoreCase("herbalism") || category.equalsIgnoreCase("woodcutting") || category.equalsIgnoreCase("misc");
}
}

View File

@@ -19,6 +19,8 @@ public class PartyHelpCommand implements CommandExecutor {
sender.sendMessage(LocaleLoader.getString("Party.Help.6", "/party kick"));
sender.sendMessage(LocaleLoader.getString("Party.Help.7", "/party leader"));
sender.sendMessage(LocaleLoader.getString("Party.Help.8", "/party disband"));
sender.sendMessage(LocaleLoader.getString("Party.Help.9", "/party itemshare"));
sender.sendMessage(LocaleLoader.getString("Party.Help.10", "/party expshare"));
return true;
default:

View File

@@ -7,6 +7,7 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -41,8 +42,8 @@ public class PartyInfoCommand implements CommandExecutor {
private String createMembersList() {
StringBuilder memberList = new StringBuilder();
for (OfflinePlayer member : playerParty.getMembers()) {
String memberName = member.getName();
for (String memberName : playerParty.getMembers()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberName);
if (playerParty.getLeader().equalsIgnoreCase(memberName)) {
memberList.append(ChatColor.GOLD);

View File

@@ -6,9 +6,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.ItemShareType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.ShareHandler;
import com.gmail.nossr50.party.ShareHandler.ShareMode;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
@@ -27,20 +27,14 @@ public class PartyItemShareCommand implements CommandExecutor {
switch (args.length) {
case 2:
playerParty = UserManager.getPlayer(sender.getName()).getParty();
ShareMode mode = ShareMode.getShareMode(args[1].toUpperCase());
if (args[1].equalsIgnoreCase("none") || CommandUtils.shouldDisableToggle(args[1])) {
handleChangingShareMode(ShareMode.NONE);
}
else if (args[1].equalsIgnoreCase("equal") || args[1].equalsIgnoreCase("even")) {
handleChangingShareMode(ShareMode.EQUAL);
}
else if (args[1].equalsIgnoreCase("random")) {
handleChangingShareMode(ShareMode.RANDOM);
}
else {
if (mode == null) {
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<NONE | EQUAL | RANDOM>"));
return true;
}
handleChangingShareMode(mode);
return true;
case 3:
@@ -54,37 +48,27 @@ public class PartyItemShareCommand implements CommandExecutor {
toggle = false;
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting> <true | false>"));
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting | misc> <true | false>"));
return true;
}
if (args[1].equalsIgnoreCase("loot")) {
playerParty.setSharingLootDrops(toggle);
try {
handleToggleItemShareCategory(ItemShareType.valueOf(args[1].toUpperCase()), toggle);
}
else if (args[1].equalsIgnoreCase("mining")) {
playerParty.setSharingMiningDrops(toggle);
}
else if (args[1].equalsIgnoreCase("herbalism")) {
playerParty.setSharingHerbalismDrops(toggle);
}
else if (args[1].equalsIgnoreCase("woodcutting")) {
playerParty.setSharingWoodcuttingDrops(toggle);
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting> <true | false>"));
catch (IllegalArgumentException ex) {
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting | misc> <true | false>"));
}
notifyToggleItemShareCategory(args[1], toggle);
return true;
default:
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<NONE | EQUAL | RANDOM>"));
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting> <true | false>"));
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting | misc> <true | false>"));
return true;
}
}
private void handleChangingShareMode(ShareHandler.ShareMode mode) {
private void handleChangingShareMode(ShareMode mode) {
playerParty.setItemShareMode(mode);
String changeModeMessage = LocaleLoader.getString("Commands.Party.SetSharing", LocaleLoader.getString("Party.ShareType.Item"), LocaleLoader.getString("Party.ShareMode." + StringUtils.getCapitalized(mode.toString())));
@@ -94,10 +78,10 @@ public class PartyItemShareCommand implements CommandExecutor {
}
}
private void notifyToggleItemShareCategory(String category, boolean toggle) {
String state = toggle ? "enabled" : "disabled";
private void handleToggleItemShareCategory(ItemShareType type, boolean toggle) {
playerParty.setSharingDrops(type, toggle);
String toggleMessage = LocaleLoader.getString("Commands.Party.ToggleShareCategory", StringUtils.getCapitalized(category), state);
String toggleMessage = LocaleLoader.getString("Commands.Party.ToggleShareCategory", StringUtils.getCapitalized(type.toString()), toggle ? "enabled" : "disabled");
for (Player member : playerParty.getOnlineMembers()) {
member.sendMessage(toggleMessage);

View File

@@ -21,7 +21,7 @@ public class PartyKickCommand implements CommandExecutor {
Party playerParty = UserManager.getPlayer(sender.getName()).getParty();
OfflinePlayer target = mcMMO.p.getServer().getOfflinePlayer(args[1]);
if (!playerParty.getMembers().contains(target)) {
if (!playerParty.getMembers().contains(target.getName())) {
sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));
return true;
}

View File

@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -76,7 +75,7 @@ public class PtpCommand implements TabExecutor {
long lastTeleport = mcMMOPlayer.getLastTeleport();
if (!SkillUtils.cooldownOver(lastTeleport * Misc.TIME_CONVERSION_FACTOR, ptpCooldown, player)) {
player.sendMessage(ChatColor.RED + "You need to wait before you can use this again! " + ChatColor.YELLOW + "(" + SkillUtils.calculateTimeLeft(lastTeleport * Misc.TIME_CONVERSION_FACTOR, ptpCooldown, player) + ")"); //TODO Locale!
player.sendMessage(LocaleLoader.getString("Item.Generic.Wait", SkillUtils.calculateTimeLeft(lastTeleport * Misc.TIME_CONVERSION_FACTOR, ptpCooldown, player)));
return true;
}
@@ -166,7 +165,7 @@ public class PtpCommand implements TabExecutor {
mcMMOPlayer.actualizeTeleportCommenceLocation(teleportingPlayer);
if (warmup > 0) {
teleportingPlayer.sendMessage(ChatColor.GRAY + "Commencing teleport in " + ChatColor.GOLD + "(" + warmup + ")" + ChatColor.GRAY + " seconds, please stand still..."); //TODO Locale!
teleportingPlayer.sendMessage(LocaleLoader.getString("Teleport.Commencing", warmup));
new TeleportationWarmup(mcMMOPlayer, mcMMOTarget).runTaskLater(mcMMO.p, 20 * warmup);
}
else {

View File

@@ -10,6 +10,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
@@ -17,6 +18,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
@@ -25,6 +27,10 @@ public class InspectCommand implements TabExecutor {
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
case 1:
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
// If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
@@ -35,6 +41,11 @@ public class InspectCommand implements TabExecutor {
return true;
}
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.enablePlayerInspectScoreboardOffline((Player) sender, profile);
return true;
}
sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", args[0]));
sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
@@ -62,6 +73,11 @@ public class InspectCommand implements TabExecutor {
return true;
}
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.enablePlayerInspectScoreboardOnline((Player) sender, mcMMOPlayer);
return true;
}
sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName()));
CommandUtils.printGatheringSkills(target, sender);
CommandUtils.printCombatSkills(target, sender);

View File

@@ -7,21 +7,18 @@ import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.LeaderboardManager;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
public class McrankCommand implements TabExecutor {
@@ -38,11 +35,12 @@ public class McrankCommand implements TabExecutor {
return true;
}
if (Config.getInstance().getUseMySQL()) {
sqlDisplay(sender, sender.getName());
if (Config.getInstance().getMcrankScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
ScoreboardManager.enablePlayerRankScoreboard((Player) sender);
}
else {
flatfileDisplay(sender, sender.getName());
display(sender, sender.getName());
}
return true;
@@ -62,18 +60,18 @@ public class McrankCommand implements TabExecutor {
if (CommandUtils.tooFar(sender, mcMMOPlayer.getPlayer(), Permissions.mcrankFar(sender))) {
return true;
}
} else if (CommandUtils.inspectOffline(sender, new PlayerProfile(playerName, false), Permissions.mcrankOffline(sender))) {
}
else if (CommandUtils.inspectOffline(sender, new PlayerProfile(playerName, false), Permissions.mcrankOffline(sender))) {
return true;
}
if (Config.getInstance().getUseMySQL()) {
sqlDisplay(sender, playerName);
if (sender instanceof Player && Config.getInstance().getMcrankScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
ScoreboardManager.enablePlayerRankScoreboardOthers((Player) sender, playerName);
}
else {
flatfileDisplay(sender, playerName);
display(sender, playerName);
}
return true;
default:
@@ -92,39 +90,7 @@ public class McrankCommand implements TabExecutor {
}
}
private void flatfileDisplay(CommandSender sender, String playerName) {
LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
for (SkillType skillType : SkillType.values()) {
int[] rankInts = LeaderboardManager.getPlayerRank(playerName, skillType);
if (!Permissions.skillEnabled(sender, skillType) || skillType.isChildSkill()) {
continue;
}
if (rankInts[1] == 0) {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), LocaleLoader.getString("Commands.mcrank.Unranked"))); // Don't bother showing ranking for players without skills
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), rankInts[0]));
}
}
// Show the powerlevel ranking
int[] rankInts = LeaderboardManager.getPlayerRank(playerName);
if (rankInts[1] == 0) {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", LocaleLoader.getString("Commands.mcrank.Unranked"))); // Don't bother showing ranking for players without skills
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", rankInts[0]));
}
}
private void sqlDisplay(CommandSender sender, String playerName) {
private void display(CommandSender sender, String playerName) {
new McrankCommandAsyncTask(playerName, sender).runTaskAsynchronously(mcMMO.p);
}
}

View File

@@ -12,7 +12,7 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
public class McstatsCommand implements TabExecutor {
@@ -27,20 +27,26 @@ public class McstatsCommand implements TabExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
Player player = mcMMOPlayer.getPlayer();
player.sendMessage(LocaleLoader.getString("Stats.Own.Stats"));
player.sendMessage(LocaleLoader.getString("mcMMO.NoSkillNote"));
CommandUtils.printGatheringSkills(player);
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = Config.getInstance().getPowerLevelCap();
if (powerLevelCap != Integer.MAX_VALUE) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
if (Config.getInstance().getMcstatsScoreboardsEnabled()) {
ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerStatsScoreboard(mcMMOPlayer);
}
else {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel()));
player.sendMessage(LocaleLoader.getString("Stats.Own.Stats"));
player.sendMessage(LocaleLoader.getString("mcMMO.NoSkillNote"));
CommandUtils.printGatheringSkills(player);
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = Config.getInstance().getPowerLevelCap();
if (powerLevelCap != Integer.MAX_VALUE) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
}
else {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel()));
}
}
return true;

View File

@@ -7,17 +7,20 @@ import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.LeaderboardManager;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
@@ -26,17 +29,14 @@ public class MctopCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
boolean useMySQL = Config.getInstance().getUseMySQL();
switch (args.length) {
case 0:
display(1, "ALL", sender, useMySQL, command);
display(1, "ALL", sender, command);
return true;
case 1:
if (StringUtils.isInt(args[0])) {
display(Math.abs(Integer.parseInt(args[0])), "ALL", sender, useMySQL, command);
display(Math.abs(Integer.parseInt(args[0])), "ALL", sender, command);
return true;
}
@@ -44,7 +44,7 @@ public class MctopCommand implements TabExecutor {
return true;
}
display(1, skill.toString(), sender, useMySQL, command);
display(1, skill.toString(), sender, command);
return true;
case 2:
@@ -56,7 +56,7 @@ public class MctopCommand implements TabExecutor {
return true;
}
display(Math.abs(Integer.parseInt(args[1])), skill.toString(), sender, useMySQL, command);
display(Math.abs(Integer.parseInt(args[1])), skill.toString(), sender, command);
return true;
default:
@@ -68,33 +68,33 @@ public class MctopCommand implements TabExecutor {
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[1], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[0], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
default:
return ImmutableList.of();
}
}
private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
private void display(int page, String skill, CommandSender sender, Command command) {
if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, this.skill)) {
sender.sendMessage(command.getPermissionMessage());
return;
}
if (sql) {
if (skill.equalsIgnoreCase("all")) {
sqlDisplay(page, "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing", sender);
}
else {
sqlDisplay(page, skill, sender);
}
if (sender instanceof Player && Config.getInstance().getMctopScoreboardEnabled()) {
ScoreboardManager.enableGlobalStatsScoreboard((Player) sender, skill, page);
}
else {
flatfileDisplay(page, skill, sender);
if (Config.getInstance().getUseMySQL()) {
sqlDisplay(page, skill, sender);
}
else {
flatfileDisplay(page, skill, sender);
}
}
}
private void flatfileDisplay(int page, String skill, CommandSender sender) {
LeaderboardManager.updateLeaderboards(); // Make sure we have the latest information
FlatfileDatabaseManager.updateLeaderboards(); // Make sure we have the latest information
if (skill.equalsIgnoreCase("all")) {
sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Leaderboard"));
@@ -105,21 +105,11 @@ public class MctopCommand implements TabExecutor {
int position = (page * 10) - 9;
for (String playerStat : LeaderboardManager.retrieveInfo(skill, page)) {
if (playerStat == null) {
continue;
}
String digit = String.valueOf(position);
if (position < 10) {
digit = "0" + digit;
}
String[] splitStat = playerStat.split(":");
for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skill, page, 10)) {
String digit = (position < 10) ? "0" : "" + String.valueOf(position);
// Format: 1. Playername - skill value
sender.sendMessage(digit + ". " + ChatColor.GREEN + splitStat[1] + " - " + ChatColor.WHITE + splitStat[0]);
sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.name + " - " + ChatColor.WHITE + stat.statVal);
position++;
}

View File

@@ -1,5 +1,8 @@
package com.gmail.nossr50.commands.skills;
import org.bukkit.block.Biome;
import org.bukkit.entity.EntityType;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -22,6 +25,7 @@ public class FishingCommand extends SkillCommand {
private boolean canShake;
private boolean canFishermansDiet;
private boolean canMasterAngler;
private boolean canIceFish;
public FishingCommand() {
super(SkillType.FISHING);
@@ -60,7 +64,18 @@ public class FishingCommand extends SkillCommand {
// MASTER ANGLER
if (canMasterAngler) {
biteChance = calculateAbilityDisplayValues((skillValue / 10) / (isStorming ? 300 : 500))[0];
double rawBiteChance = ((Math.max((skillValue / 200.0), 1.0)) / (isStorming ? 300 : 500));
Biome biome = player.getLocation().getBlock().getBiome();
if (biome == Biome.RIVER || biome == Biome.OCEAN) {
rawBiteChance = rawBiteChance * 2.0;
}
if (player.isInsideVehicle() && player.getVehicle().getType() == EntityType.BOAT) {
rawBiteChance = rawBiteChance * 2.0;
}
biteChance = calculateAbilityDisplayValues(rawBiteChance * 100.0)[0];
}
}
@@ -71,11 +86,12 @@ public class FishingCommand extends SkillCommand {
canShake = Permissions.shake(player);
canFishermansDiet = Permissions.fishermansDiet(player);
canMasterAngler = Permissions.masterAngler(player);
canIceFish = Permissions.iceFishing(player);
}
@Override
protected boolean effectsHeaderPermissions() {
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet;
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet || canIceFish;
}
@Override
@@ -101,11 +117,15 @@ public class FishingCommand extends SkillCommand {
if (canMasterAngler) {
player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Fishing.Effect.8"), LocaleLoader.getString("Fishing.Effect.9")));
}
if (canIceFish) {
player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Fishing.Effect.10"), LocaleLoader.getString("Fishing.Effect.11")));
}
}
@Override
protected boolean statsHeaderPermissions() {
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet;
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet || canIceFish;
}
@Override
@@ -136,5 +156,16 @@ public class FishingCommand extends SkillCommand {
if (canFishermansDiet) {
player.sendMessage(LocaleLoader.getString("Fishing.Ability.FD", fishermansDietRank));
}
if (canIceFish) {
int unlockLevel = AdvancedConfig.getInstance().getIceFishingUnlockLevel();
if (skillValue < unlockLevel) {
player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Fishing.Ability.Locked.1", unlockLevel)));
}
else {
player.sendMessage(LocaleLoader.getString("Fishing.Ability.IceFishing"));
}
}
}
}

View File

@@ -41,10 +41,10 @@ public class RepairCommand extends SkillCommand {
@Override
protected void dataCalculations() {
// We're using pickaxes here, not the best but it works
Repairable diamondRepairable = mcMMO.repairableManager.getRepairable(Material.DIAMOND_PICKAXE.getId());
Repairable goldRepairable = mcMMO.repairableManager.getRepairable(Material.GOLD_PICKAXE.getId());
Repairable ironRepairable = mcMMO.repairableManager.getRepairable(Material.IRON_PICKAXE.getId());
Repairable stoneRepairable = mcMMO.repairableManager.getRepairable(Material.STONE_PICKAXE.getId());
Repairable diamondRepairable = mcMMO.getRepairableManager().getRepairable(Material.DIAMOND_PICKAXE.getId());
Repairable goldRepairable = mcMMO.getRepairableManager().getRepairable(Material.GOLD_PICKAXE.getId());
Repairable ironRepairable = mcMMO.getRepairableManager().getRepairable(Material.IRON_PICKAXE.getId());
Repairable stoneRepairable = mcMMO.getRepairableManager().getRepairable(Material.STONE_PICKAXE.getId());
// TODO: This isn't really accurate - if they don't have pickaxes loaded it doesn't always mean the repair level is 0
diamondLevel = (diamondRepairable == null) ? 0 : diamondRepairable.getMinimumLevel();

View File

@@ -11,6 +11,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
@@ -20,6 +21,7 @@ import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.PerksUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
@@ -71,7 +73,14 @@ public abstract class SkillCommand implements TabExecutor {
if (!skill.isChildSkill()) {
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
if (Config.getInstance().getSkillScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerSkillScoreboard(mcMMOPlayer, skill);
}
else {
player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
}
}
else {
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child")));

View File

@@ -22,7 +22,7 @@ public abstract class SpoutCommand implements TabExecutor {
return true;
}
if (!mcMMO.spoutEnabled || !SpoutConfig.getInstance().getXPBarEnabled()) {
if (!mcMMO.isSpoutEnabled() || !SpoutConfig.getInstance().getXPBarEnabled()) {
sender.sendMessage(LocaleLoader.getString("Commands.Disabled"));
return true;
}

View File

@@ -52,6 +52,8 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
public double getRetrieveChanceMax() { return config.getDouble("Skills.Archery.Retrieve_MaxBonus", 100.0D); }
public int getRetrieveMaxBonusLevel() { return config.getInt("Skills.Archery.Retrieve_MaxBonusLevel", 1000); }
public double getForceMultiplier() { return config.getDouble("Skills.Archery.Force_Multiplier", 2.0D); }
/* AXES */
public int getBonusDamageAxesBonusMax() { return config.getInt("Skills.Axes.DamageIncrease_MaxBonus", 4); }
public int getBonusDamageAxesMaxBonusLevel() { return config.getInt("Skills.Axes.DamageIncrease_MaxBonusLevel", 200); }
@@ -85,6 +87,8 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
public int getFishermanDietRankChange() { return config.getInt("Skills.Fishing.Fisherman_Diet_RankChange", 200); }
public int getIceFishingUnlockLevel() { return config.getInt("Skills.Fishing.Ice_Fishing_UnlockLevel", 50); }
/* Shake */
public int getShakeUnlockLevel() { return config.getInt("Skills.Fishing.Shake_UnlockLevel", 150); }
public int getShakeChanceRank1() { return config.getInt("Skills.Fishing.Shake_Chance.Rank_1", 25); }
@@ -273,9 +277,17 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
public double getWoodcuttingDoubleDropChance() { return config.getDouble("Skills.Woodcutting.DoubleDrops_ChanceMax", 100.0D); }
public int getWoodcuttingDoubleDropMaxLevel() { return config.getInt("Skills.Woodcutting.DoubleDrops_MaxBonusLevel", 1000); }
/* SPOUT STUFF*/
public int getSpoutNotificationTier1() { return config.getInt("Spout.Notifications.Tier1", 200); }
public int getSpoutNotificationTier2() { return config.getInt("Spout.Notifications.Tier2", 400); }
public int getSpoutNotificationTier3() { return config.getInt("Spout.Notifications.Tier3", 600); }
public int getSpoutNotificationTier4() { return config.getInt("Spout.Notifications.Tier4", 800); }
/* KRAKEN STUFF */
public boolean getKrakenEnabled() { return config.getBoolean("Kraken.Enabled", true); }
public boolean getKrakenGlobalSoundsEnabled() { return config.getBoolean("Kraken.Global_Sounds", true); }
public boolean getKrakenEscapeAllowed() { return config.getBoolean("Kraken.Allow_Escaping", false); }
public int getKrakenTriesBeforeRelease() { return config.getInt("Kraken.Tries_Before_Release", 50); }
public int getKrakenHealth() { return config.getInt("Kraken.Health", 50); }
public String getKrakenName() { return config.getString("Kraken.Name", "The Kraken"); }
public String getServerUnleashMessage() { return config.getString("Kraken.Unleashed_Message.Server", "(PLAYER) has unleashed the kraken!"); }
public String getPlayerUnleashMessage() { return config.getString("Kraken.Unleashed_Message.Player", "THE KRAKEN HAS BEEN UNLEASHED!"); }
public String getPlayerDefeatMessage() { return config.getString("Kraken.Defeated_Message.Killed", "You have slain the kraken!"); }
public String getPlayerEscapeMessage() { return config.getString("Kraken.Defeated_Message.Escape", "You have escaped from the kraken!"); }
public int getKrakenAttackInterval() { return config.getInt("Kraken.Attack_Interval_Seconds", 1); }
public int getKrakenAttackDamage() { return config.getInt("Kraken.Attack_Damage", 1); }
}

View File

@@ -46,6 +46,9 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getVerboseLoggingEnabled() { return config.getBoolean("General.Verbose_Logging", false); }
public boolean getConfigOverwriteEnabled() { return config.getBoolean("General.Config_Update_Overwrite", true); }
public boolean getPotatoEnabled() { return config.getBoolean("General.Potato_Explosion_Enabled", false); }
public int getPotatoChance() { return config.getInt("General.Potato_Explosion_Chance", 1); }
public boolean getPartyDisplayNames() { return config.getBoolean("Commands.p.Use_Display_Names", true); }
public boolean getAdminDisplayNames() { return config.getBoolean("Commands.a.Use_Display_Names", true); }
@@ -61,6 +64,24 @@ public class Config extends AutoUpdateConfigLoader {
public int getMobHealthbarTime() { return config.getInt("Mob_Healthbar.Display_Time", 3); }
/* Scoreboards */
public boolean getMcrankScoreboardEnabled() { return config.getBoolean("Scoreboards.Mcrank.Use", true); }
public int getMcrankScoreboardTime() { return config.getInt("Scoreboards.Mcrank.Display_Time", 10); }
public boolean getMcstatsScoreboardsEnabled() { return config.getBoolean("Scoreboards.Mcstats.Use", true); }
public int getMcstatsScoreboardTime() { return config.getInt("Scoreboards.Mcstats.Display_Time", 10); }
public boolean getMctopScoreboardEnabled() { return config.getBoolean("Scoreboards.Mctop.Use", true); }
public int getMctopScoreboardTime() { return config.getInt("Scoreboards.Mctop.Display_Time", 10); }
public boolean getInspectScoreboardEnabled() { return config.getBoolean("Scoreboards.Inspect.Use", true); }
public int getInspectScoreboardTime() { return config.getInt("Scoreboards.Inspect.Display_Time", 10); }
public boolean getSkillScoreboardEnabled() { return config.getBoolean("Scoreboards.Skillname.Use", true); }
public int getSkillScoreboardTime() { return config.getInt("Scoreboards.Skillname.Display_Time", 10); }
public boolean getPowerLevelsEnabled() { return config.getBoolean("Scoreboards.Power_Level.Use", true); }
/* Database Purging */
public int getPurgeInterval() { return config.getInt("Database_Purging.Purge_Interval", -1); }
public int getOldUsersCutoff() { return config.getInt("Database_Purging.Old_User_Cutoff", 6); }
@@ -131,6 +152,7 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getGreaterImpactEffectEnabled() { return config.getBoolean("Particles.Greater_Impact", true); }
public boolean getLevelUpEffectsEnabled() { return config.getBoolean("Particles.LevelUp_Enabled", true); }
public int getLevelUpEffectsTier() { return config.getInt("Particles.LevelUp_Tier", 100); }
public boolean getLargeFireworks() { return config.getBoolean("Particles.LargeFireworks", true); }
/* PARTY SETTINGS */
public int getAutoPartyKickInterval() { return config.getInt("Party.AutoKick_Interval", 12); }
@@ -208,6 +230,7 @@ public class Config extends AutoUpdateConfigLoader {
public int getSalvageAnvilId() { return config.getInt("Skills.Repair.Salvage_Anvil_ID", 41); }
public boolean getSalvageTools() { return config.getBoolean("Skills.Repair.Salvage_tools", true); }
public boolean getSalvageArmor() { return config.getBoolean("Skills.Repair.Salvage_armor", true); }
public boolean getRepairConfirmRequired() { return config.getBoolean("Skills.Repair.Confirm_Required", true); }
/* Unarmed */
public boolean getUnarmedBlockCrackerSmoothbrickToCracked() { return config.getBoolean("Skills.Unarmed.Block_Cracker.SmoothBrick_To_CrackedBrick", true); }
@@ -255,7 +278,6 @@ public class Config extends AutoUpdateConfigLoader {
*/
/* General Settings */
public boolean getExperienceGainsMobspawnersEnabled() { return config.getBoolean("Experience.Gains.Mobspawners.Enabled", false); }
public boolean getExperienceGainsPlayerVersusPlayerEnabled() { return config.getBoolean("Experience.PVP.Rewards", true); }
public double getExperienceGainsGlobalMultiplier() { return config.getDouble("Experience.Gains.Multiplier.Global", 1.0); }
@@ -268,6 +290,7 @@ public class Config extends AutoUpdateConfigLoader {
public double getAnimalsXP() { return config.getDouble("Experience.Combat.Multiplier.Animals", 1.0); }
public double getWitherSkeletonXP() { return config.getDouble("Experience.Combat.Multiplier.Wither_Skeleton", 4.0); }
public double getSpawnedMobXpMultiplier() { return config.getDouble("Experience.Gains.MobSpawners.Multiplier", 0.0); }
/* XP Formula Multiplier */
public int getFormulaMultiplierCurve() { return config.getInt("Experience.Formula.Curve_Modifier", 20); }

View File

@@ -1,7 +1,9 @@
package com.gmail.nossr50.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -30,11 +32,11 @@ public abstract class ConfigLoader {
protected void loadFile() {
if (!configFile.exists()) {
plugin.getLogger().info("Creating mcMMO " + fileName + " File...");
plugin.debug("Creating mcMMO " + fileName + " File...");
createFile();
}
else {
plugin.getLogger().info("Loading mcMMO " + fileName + " File...");
plugin.debug("Loading mcMMO " + fileName + " File...");
}
config = YamlConfiguration.loadConfiguration(configFile);
@@ -43,38 +45,49 @@ public abstract class ConfigLoader {
protected abstract void loadKeys();
protected void createFile() {
if (configFile.exists()) {
return;
}
configFile.getParentFile().mkdirs();
InputStream inputStream = plugin.getResource(fileName);
if (inputStream != null) {
try {
copyStreamToFile(inputStream, configFile);
if (inputStream == null) {
plugin.getLogger().severe("Missing resource file: '" + fileName + "' please notify the plugin authors");
return;
}
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(configFile);
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
catch (Exception e) {
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (outputStream != null) {
try {
outputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
plugin.getLogger().severe("Missing resource file: '" + fileName + "' please notify the plugin authors");
}
}
private static void copyStreamToFile(InputStream inputStream, File file) throws Exception {
OutputStream outputStream = new FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
inputStream.close();
outputStream.close();
}
}

View File

@@ -1,5 +1,7 @@
package com.gmail.nossr50.config.party;
import java.util.HashSet;
import org.bukkit.Material;
import com.gmail.nossr50.config.ConfigLoader;
@@ -21,13 +23,20 @@ public class ItemWeightConfig extends ConfigLoader {
}
public int getItemWeight(Material material) {
String materialName = StringUtils.getPrettyItemString(material).replace(" ", "_");
int itemWeight = config.getInt("Item_Weights.Default");
return config.getInt("Item_Weights." + StringUtils.getPrettyItemString(material).replace(" ", "_"), config.getInt("Item_Weights.Default"));
}
if (config.getInt("Item_Weights." + materialName) > 0) {
itemWeight = config.getInt("Item_Weights." + materialName);
public HashSet<Material> getMiscItems() {
HashSet<Material> miscItems = new HashSet<Material>();
for (String item : config.getStringList("Party_Shareables.Misc_Items")) {
Material material = Material.getMaterial(item.toUpperCase());
if (material != null) {
miscItems.add(material);
}
}
return itemWeight;
return miscItems;
}
@Override

View File

@@ -1,5 +1,7 @@
package com.gmail.nossr50.config.spout;
import org.getspout.spoutapi.keyboard.Keyboard;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.datatypes.spout.huds.HudType;
@@ -34,7 +36,14 @@ public class SpoutConfig extends ConfigLoader {
}
public boolean getShowPowerLevel() { return config.getBoolean("HUD.Show_Power_Level", true); }
public String getMenuKey() { return config.getString("Menu.Key", "KEY_M"); }
public Keyboard getMenuKey() {
try {
return Keyboard.valueOf(config.getString("Menu.Key", "KEY_M").toUpperCase().trim());
}
catch (IllegalArgumentException ex) {
return Keyboard.KEY_M;
}
}
/* XP Bar */
public boolean getXPBarEnabled() { return config.getBoolean("XP.Bar.Enabled", true); }
@@ -57,4 +66,10 @@ public class SpoutConfig extends ConfigLoader {
public double getRetroHUDRed(SkillType skill) { return config.getDouble("HUD.Retro.Colors." + skill.toString().toLowerCase() +".RED", 0.3); }
public double getRetroHUDGreen(SkillType skill) { return config.getDouble("HUD.Retro.Colors." + skill.toString().toLowerCase() +".RED", 0.3); }
public double getRetroHUDBlue(SkillType skill) { return config.getDouble("HUD.Retro.Colors." + skill.toString().toLowerCase() +".RED", 0.3); }
/* Notification Tiers */
public int getNotificationTier1() { return config.getInt("Notifications.Tier1", 200); }
public int getNotificationTier2() { return config.getInt("Notifications.Tier2", 400); }
public int getNotificationTier3() { return config.getInt("Notifications.Tier3", 600); }
public int getNotificationTier4() { return config.getInt("Notifications.Tier4", 800); }
}

View File

@@ -117,7 +117,7 @@ public class TreasureConfig extends ConfigLoader {
reason.add("Invalid amount: " + amount);
}
if (data > 127 || data < -128) {
if (id < 256 && (data > 127 || data < -128)) {
reason.add("Invalid data: " + data);
}
@@ -192,7 +192,7 @@ public class TreasureConfig extends ConfigLoader {
treasures.put(treasureName, fTreasure);
}
}
else if (config.getBoolean("Treasures." + treasureName + "Drops_From.Shake", false)) {
else if (config.getBoolean("Treasures." + treasureName + ".Drops_From.Shake", false)) {
if (config.getConfigurationSection("Treasures." + treasureName + ".Drops_From").getKeys(false).size() != 1) {
reason.add("This can only be a shake drop.");
}

View File

@@ -1,654 +1,63 @@
package com.gmail.nossr50.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.io.File;
import java.io.IOException;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.DatabaseUpdateType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
import com.gmail.nossr50.util.Misc;
public final class DatabaseManager {
private static String connectionString;
public class DatabaseManager {
private final mcMMO plugin;
private final boolean isUsingSQL;
private File usersFile;
private static String tablePrefix = Config.getInstance().getMySQLTablePrefix();
private static Connection connection = null;
public DatabaseManager(final mcMMO plugin, final boolean isUsingSQL) {
this.plugin = plugin;
this.isUsingSQL = isUsingSQL;
// Scale waiting time by this much per failed attempt
private static final double SCALING_FACTOR = 40;
// Minimum wait in nanoseconds (default 500ms)
private static final long MIN_WAIT = 500L * 1000000L;
// Maximum time to wait between reconnects (default 5 minutes)
private static final long MAX_WAIT = 5L * 60L * 1000L * 1000000L;
// How long to wait when checking if connection is valid (default 3 seconds)
private static final int VALID_TIMEOUT = 3;
// When next to try connecting to Database in nanoseconds
private static long nextReconnectTimestamp = 0L;
// How many connection attempts have failed
private static int reconnectAttempt = 0;
private static final long ONE_MONTH = 2630000000L;
private DatabaseManager() {}
/**
* Attempt to connect to the mySQL database.
*/
public static void connect() {
Config configInstance = Config.getInstance();
connectionString = "jdbc:mysql://" + configInstance.getMySQLServerName() + ":" + configInstance.getMySQLServerPort() + "/" + configInstance.getMySQLDatabaseName();
try {
mcMMO.p.getLogger().info("Attempting connection to MySQL...");
// Force driver to load if not yet loaded
Class.forName("com.mysql.jdbc.Driver");
Properties connectionProperties = new Properties();
connectionProperties.put("user", configInstance.getMySQLUserName());
connectionProperties.put("password", configInstance.getMySQLUserPassword());
connectionProperties.put("autoReconnect", "false");
connectionProperties.put("maxReconnects", "0");
connection = DriverManager.getConnection(connectionString, connectionProperties);
mcMMO.p.getLogger().info("Connection to MySQL was a success!");
if (isUsingSQL) {
SQLDatabaseManager.checkConnected();
SQLDatabaseManager.createStructure();
}
catch (SQLException ex) {
connection = null;
if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
mcMMO.p.getLogger().info("Connection to MySQL failed!");
}
}
catch (ClassNotFoundException ex) {
connection = null;
if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
mcMMO.p.getLogger().info("MySQL database driver not found!");
}
else {
usersFile = new File(mcMMO.getUsersFilePath());
createFlatfileDatabase();
FlatfileDatabaseManager.updateLeaderboards();
}
}
/**
* Attempt to create the database structure.
*/
public static void createStructure() {
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ "`user` varchar(40) NOT NULL,"
+ "`lastlogin` int(32) unsigned NOT NULL,"
+ "PRIMARY KEY (`id`),"
+ "UNIQUE KEY `user` (`user`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`hudtype` varchar(50) NOT NULL DEFAULT 'STANDARD',"
+ "`mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS',"
+ "PRIMARY KEY (`user_id`),"
+ "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
+ "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "cooldowns` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`),"
+ "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
+ "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`),"
+ "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
+ "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "experience` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`),"
+ "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
+ "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
checkDatabaseStructure(DatabaseUpdateType.FISHING);
checkDatabaseStructure(DatabaseUpdateType.BLAST_MINING);
checkDatabaseStructure(DatabaseUpdateType.CASCADE_DELETE);
checkDatabaseStructure(DatabaseUpdateType.INDEX);
checkDatabaseStructure(DatabaseUpdateType.MOB_HEALTHBARS);
public void purgePowerlessUsers() {
plugin.getLogger().info("Purging powerless users...");
plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgePowerlessSQL() : FlatfileDatabaseManager.purgePowerlessFlatfile()) + " users from the database.");
}
/**
* Attempt to write the SQL query.
*
* @param sql Query to write.
* @return true if the query was successfully written, false otherwise.
*/
public static boolean write(String sql) {
if (!checkConnected()) {
return false;
}
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
statement.executeUpdate();
return true;
}
catch (SQLException ex) {
printErrors(ex);
return false;
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
return false;
}
}
}
public void purgeOldUsers() {
plugin.getLogger().info("Purging old users...");
plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgeOldSQL() : FlatfileDatabaseManager.removeOldFlatfileUsers()) + " users from the database.");
}
/**
* Returns the number of rows affected by either a DELETE or UPDATE query
*
* @param sql SQL query to execute
* @return the number of rows affected
*/
public static int update(String sql) {
int ret = 0;
if (checkConnected()) {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
ret = statement.executeUpdate();
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
}
return ret;
}
/**
* Get the Integer. Only return first row / first field.
*
* @param sql SQL query to execute
* @return the value in the first row / first field
*/
public static int getInt(String sql) {
ResultSet resultSet = null;
int result = 0;
if (checkConnected()) {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
if (resultSet.next()) {
result = resultSet.getInt(1);
}
else {
result = 0;
}
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
}
return result;
}
/**
* Check connection status and re-establish if dead or stale.
*
* If the very first immediate attempt fails, further attempts
* will be made in progressively larger intervals up to MAX_WAIT
* intervals.
*
* This allows for MySQL to time out idle connections as needed by
* server operator, without affecting McMMO, while still providing
* protection against a database outage taking down Bukkit's tick
* processing loop due to attemping a database connection each
* time McMMO needs the database.
*
* @return the boolean value for whether or not we are connected
*/
public static boolean checkConnected() {
boolean isClosed = true;
boolean isValid = false;
boolean exists = (connection != null);
// If we're waiting for server to recover then leave early
if (nextReconnectTimestamp > 0 && nextReconnectTimestamp > System.nanoTime()) {
return false;
}
if (exists) {
try {
isClosed = connection.isClosed();
}
catch (SQLException e) {
isClosed = true;
e.printStackTrace();
printErrors(e);
}
if (!isClosed) {
try {
isValid = connection.isValid(VALID_TIMEOUT);
}
catch (SQLException e) {
// Don't print stack trace because it's valid to lose idle connections to the server and have to restart them.
isValid = false;
}
}
}
// Leave if all ok
if (exists && !isClosed && isValid) {
// Housekeeping
nextReconnectTimestamp = 0;
reconnectAttempt = 0;
public boolean removeUser(String playerName) {
if (isUsingSQL ? SQLDatabaseManager.removeUserSQL(playerName) : FlatfileDatabaseManager.removeFlatFileUser(playerName)) {
Misc.profileCleanup(playerName);
return true;
}
// Cleanup after ourselves for GC and MySQL's sake
if (exists && !isClosed) {
try {
connection.close();
}
catch (SQLException ex) {
// This is a housekeeping exercise, ignore errors
}
}
// Try to connect again
connect();
// Leave if connection is good
try {
if (connection != null && !connection.isClosed()) {
// Schedule a database save if we really had an outage
if (reconnectAttempt > 1) {
new SQLReconnectTask().runTaskLater(mcMMO.p, 5);
}
nextReconnectTimestamp = 0;
reconnectAttempt = 0;
return true;
}
}
catch (SQLException e) {
// Failed to check isClosed, so presume connection is bad and attempt later
e.printStackTrace();
printErrors(e);
}
reconnectAttempt++;
nextReconnectTimestamp = (long)(System.nanoTime() + Math.min(MAX_WAIT, (reconnectAttempt * SCALING_FACTOR * MIN_WAIT)));
return false;
}
/**
* Read SQL query.
*
* @param sql SQL query to read
* @return the rows in this SQL query
*/
public static HashMap<Integer, ArrayList<String>> read(String sql) {
ResultSet resultSet;
HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
if (checkConnected()) {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
ArrayList<String> column = new ArrayList<String>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
column.add(resultSet.getString(i));
}
rows.put(resultSet.getRow(), column);
}
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
private void createFlatfileDatabase() {
if (usersFile.exists()) {
return;
}
return rows;
}
usersFile.getParentFile().mkdir();
public static Map<String, Integer> readSQLRank(String playerName) {
ResultSet resultSet;
Map<String, Integer> skills = new HashMap<String, Integer>();
if (checkConnected()) {
try {
for (SkillType skillType : SkillType.values()) {
if (skillType.isChildSkill()) {
continue;
}
String skillName = skillType.name().toLowerCase();
String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
"AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
resultSet.next();
int rank = resultSet.getInt("rank");
sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
"AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = '" + playerName + "') ORDER BY user";
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
skills.put(skillType.name(), rank + resultSet.getRow());
break;
}
}
statement.close();
}
String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
"AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > " +
"(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
resultSet.next();
int rank = resultSet.getInt("rank");
sql = "SELECT user, taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
"AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing = " +
"(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
while (resultSet.next()) {
if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
skills.put("ALL", rank + resultSet.getRow());
break;
}
}
statement.close();
}
catch (SQLException ex) {
printErrors(ex);
}
}
return skills;
}
public static void purgePowerlessSQL() {
mcMMO.p.getLogger().info("Purging powerless users...");
HashMap<Integer, ArrayList<String>> usernames;
usernames = read("SELECT u.user FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u " + "WHERE s.user_id = u.id AND " +
"(s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0");
write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM " +
"(SELECT u.id FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u " + "WHERE s.user_id = u.id " +
"AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0) AS p)");
int purgedUsers = 0;
for (int i = 1; i <= usernames.size(); i++) {
String playerName = usernames.get(i).get(0);
if (playerName == null || mcMMO.p.getServer().getOfflinePlayer(playerName).isOnline()) {
continue;
}
Misc.profileCleanup(playerName);
purgedUsers++;
}
mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
}
public static void purgeOldSQL() {
mcMMO.p.getLogger().info("Purging old users...");
long currentTime = System.currentTimeMillis();
long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
HashMap<Integer, ArrayList<String>> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")");
write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM (SELECT id FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")) AS p)");
int purgedUsers = 0;
for (int i = 1; i <= usernames.size(); i++) {
String playerName = usernames.get(i).get(0);
if (playerName == null) {
continue;
}
Misc.profileCleanup(playerName);
purgedUsers++;
}
mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
}
/**
* Check database structure for missing values.
*
* @param update Type of data to check updates for
*/
private static void checkDatabaseStructure(DatabaseUpdateType update) {
String sql = null;
ResultSet resultSet = null;
HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
switch (update) {
case BLAST_MINING:
sql = "SELECT * FROM `" + tablePrefix + "cooldowns` ORDER BY `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30";
break;
case CASCADE_DELETE:
write("ALTER TABLE `" + tablePrefix + "huds` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
write("ALTER TABLE `" + tablePrefix + "experience` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
write("ALTER TABLE `" + tablePrefix + "cooldowns` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
write("ALTER TABLE `" + tablePrefix + "skills` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
break;
case FISHING:
sql = "SELECT * FROM `" + tablePrefix + "experience` ORDER BY `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30";
break;
case INDEX:
if (read("SHOW INDEX FROM " + tablePrefix + "skills").size() != 13 && checkConnected()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
write("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_taming` (`taming`) USING BTREE, "
+ "ADD INDEX `idx_mining` (`mining`) USING BTREE, "
+ "ADD INDEX `idx_woodcutting` (`woodcutting`) USING BTREE, "
+ "ADD INDEX `idx_repair` (`repair`) USING BTREE, "
+ "ADD INDEX `idx_unarmed` (`unarmed`) USING BTREE, "
+ "ADD INDEX `idx_herbalism` (`herbalism`) USING BTREE, "
+ "ADD INDEX `idx_excavation` (`excavation`) USING BTREE, "
+ "ADD INDEX `idx_archery` (`archery`) USING BTREE, "
+ "ADD INDEX `idx_swords` (`swords`) USING BTREE, "
+ "ADD INDEX `idx_axes` (`axes`) USING BTREE, "
+ "ADD INDEX `idx_acrobatics` (`acrobatics`) USING BTREE, "
+ "ADD INDEX `idx_fishing` (`fishing`) USING BTREE;");
}
break;
case MOB_HEALTHBARS:
sql = "SELECT * FROM `" + tablePrefix + "huds` ORDER BY `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30";
break;
default:
break;
}
PreparedStatement statement = null;
try {
if (!checkConnected()) {
return;
}
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
ArrayList<String> column = new ArrayList<String>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
column.add(resultSet.getString(i));
}
rows.put(resultSet.getRow(), column);
}
plugin.debug("Creating mcmmo.users file...");
new File(mcMMO.getUsersFilePath()).createNewFile();
}
catch (SQLException ex) {
switch (update) {
case BLAST_MINING:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
write("ALTER TABLE `"+tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' ;");
break;
case FISHING:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
write("ALTER TABLE `"+tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
write("ALTER TABLE `"+tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
break;
case MOB_HEALTHBARS:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
write("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS' ;");
break;
default:
break;
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (resultSet != null) {
try {
resultSet.close();
}
catch (SQLException e) {
// Ignore the error, we're leaving
}
}
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
// Ignore the error, we're leaving
}
}
}
}
private static void printErrors(SQLException ex) {
mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
}
}

View File

@@ -9,6 +9,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
@@ -16,7 +17,7 @@ import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.util.StringUtils;
public final class LeaderboardManager {
public final class FlatfileDatabaseManager {
private static HashMap<SkillType, List<PlayerStat>> playerStatHash = new HashMap<SkillType, List<PlayerStat>>();
private static List<PlayerStat> powerLevels = new ArrayList<PlayerStat>();
private static long lastUpdate = 0;
@@ -24,7 +25,7 @@ public final class LeaderboardManager {
private static final long UPDATE_WAIT_TIME = 600000L; // 10 minutes
private static final long ONE_MONTH = 2630000000L;
private LeaderboardManager() {}
private FlatfileDatabaseManager() {}
/**
* Update the leader boards.
@@ -35,6 +36,7 @@ public final class LeaderboardManager {
return;
}
String usersFilePath = mcMMO.getUsersFilePath();
lastUpdate = System.currentTimeMillis(); // Log when the last update was run
powerLevels.clear(); // Clear old values from the power levels
@@ -54,8 +56,7 @@ public final class LeaderboardManager {
// Read from the FlatFile database and fill our arrays with information
try {
FileReader file = new FileReader(mcMMO.getUsersFilePath());
BufferedReader in = new BufferedReader(file);
BufferedReader in = new BufferedReader(new FileReader(usersFilePath));
String line = "";
ArrayList<String> players = new ArrayList<String>();
@@ -72,72 +73,25 @@ public final class LeaderboardManager {
players.add(playerName);
if (data.length > 1 && StringUtils.isInt(data[1])) {
mining.add(new PlayerStat(playerName, Integer.parseInt(data[1])));
powerLevel += Integer.parseInt(data[1]);
}
if (data.length > 5 && StringUtils.isInt(data[5])) {
woodcutting.add(new PlayerStat(playerName, Integer.parseInt(data[5])));
powerLevel += Integer.parseInt(data[5]);
}
if (data.length > 7 && StringUtils.isInt(data[7])) {
repair.add(new PlayerStat(playerName, Integer.parseInt(data[7])));
powerLevel += Integer.parseInt(data[7]);
}
if (data.length > 8 && StringUtils.isInt(data[8])) {
unarmed.add(new PlayerStat(playerName, Integer.parseInt(data[8])));
powerLevel += Integer.parseInt(data[8]);
}
if (data.length > 9 && StringUtils.isInt(data[9])) {
herbalism.add(new PlayerStat(playerName, Integer.parseInt(data[9])));
powerLevel += Integer.parseInt(data[9]);
}
if (data.length > 10 && StringUtils.isInt(data[10])) {
excavation.add(new PlayerStat(playerName, Integer.parseInt(data[10])));
powerLevel += Integer.parseInt(data[10]);
}
if (data.length > 11 && StringUtils.isInt(data[11])) {
archery.add(new PlayerStat(playerName, Integer.parseInt(data[11])));
powerLevel += Integer.parseInt(data[11]);
}
if (data.length > 12 && StringUtils.isInt(data[12])) {
swords.add(new PlayerStat(playerName, Integer.parseInt(data[12])));
powerLevel += Integer.parseInt(data[12]);
}
if (data.length > 13 && StringUtils.isInt(data[13])) {
axes.add(new PlayerStat(playerName, Integer.parseInt(data[13])));
powerLevel += Integer.parseInt(data[13]);
}
if (data.length > 14 && StringUtils.isInt(data[14])) {
acrobatics.add(new PlayerStat(playerName, Integer.parseInt(data[14])));
powerLevel += Integer.parseInt(data[14]);
}
if (data.length > 24 && StringUtils.isInt(data[24])) {
taming.add(new PlayerStat(playerName, Integer.parseInt(data[24])));
powerLevel += Integer.parseInt(data[24]);
}
if (data.length > 34 && StringUtils.isInt(data[34])) {
fishing.add(new PlayerStat(playerName, Integer.parseInt(data[34])));
powerLevel += Integer.parseInt(data[34]);
}
powerLevel += loadStat(mining, playerName, data, 1);
powerLevel += loadStat(woodcutting, playerName, data, 5);
powerLevel += loadStat(repair, playerName, data, 7);
powerLevel += loadStat(unarmed, playerName, data, 8);
powerLevel += loadStat(herbalism, playerName, data, 9);
powerLevel += loadStat(excavation, playerName, data, 10);
powerLevel += loadStat(archery, playerName, data, 11);
powerLevel += loadStat(swords, playerName, data, 12);
powerLevel += loadStat(axes, playerName, data, 13);
powerLevel += loadStat(acrobatics, playerName, data, 14);
powerLevel += loadStat(taming, playerName, data, 24);
powerLevel += loadStat(fishing, playerName, data, 34);
powerLevels.add(new PlayerStat(playerName, powerLevel));
}
in.close();
}
catch (Exception e) {
mcMMO.p.getLogger().severe("Exception while reading " + mcMMO.getUsersFilePath() + " (Are you sure you formatted it correctly?)" + e.toString());
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
SkillComparator c = new SkillComparator();
@@ -177,38 +131,11 @@ public final class LeaderboardManager {
* @param pageNumber Which page in the leaderboards to retrieve
* @return the requested leaderboard information
*/
public static String[] retrieveInfo(String skillType, int pageNumber) {
String[] info = new String[10];
List<PlayerStat> statsList;
public static List<PlayerStat> retrieveInfo(String skillType, int pageNumber, int statsPerPage) {
List<PlayerStat> statsList = skillType.equalsIgnoreCase("all") ? powerLevels : playerStatHash.get(SkillType.getSkill(skillType));
int fromIndex = (Math.max(pageNumber, 1) - 1) * statsPerPage;
if (skillType.equalsIgnoreCase("all")) {
statsList = powerLevels;
}
else {
statsList = playerStatHash.get(SkillType.getSkill(skillType));
}
if (pageNumber < 1) {
pageNumber = 1;
}
int destination = (pageNumber - 1) * 10;
for (int i = 0; i < 10; i++) {
if (destination + i < statsList.size()) {
PlayerStat ps = statsList.get(destination + i);
info[i] = ps.name + ":" + ps.statVal;
}
}
return info;
}
public static int[] getPlayerRank(String playerName) {
return getPlayerRank(playerName, powerLevels);
}
public static int[] getPlayerRank(String playerName, SkillType skillType) {
return getPlayerRank(playerName, playerStatHash.get(skillType));
return statsList.subList(Math.min(fromIndex, statsList.size()), Math.min(fromIndex + statsPerPage, statsList.size()));
}
public static boolean removeFlatFileUser(String playerName) {
@@ -266,7 +193,7 @@ public final class LeaderboardManager {
return worked;
}
public static void purgePowerlessFlatfile() {
public static int purgePowerlessFlatfile() {
mcMMO.p.getLogger().info("Purging powerless users...");
int purgedUsers = 0;
@@ -277,16 +204,10 @@ public final class LeaderboardManager {
}
}
mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
return purgedUsers;
}
public static void purgeOldFlatfile() {
mcMMO.p.getLogger().info("Purging old users...");
int purgedUsers = removeOldFlatfileUsers();
mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
}
private static int removeOldFlatfileUsers() {
public static int removeOldFlatfileUsers() {
int removedPlayers = 0;
long currentTime = System.currentTimeMillis();
long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
@@ -350,22 +271,55 @@ public final class LeaderboardManager {
return removedPlayers;
}
private static int[] getPlayerRank(String playerName, List<PlayerStat> statsList) {
private static Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
int currentPos = 1;
if (statsList == null) {
return new int[] {0, 0};
return null;
}
for (PlayerStat stat : statsList) {
if (stat.name.equalsIgnoreCase(playerName)) {
return new int[] {currentPos, stat.statVal};
return currentPos;
}
currentPos++;
}
return new int[] {0, 0};
return null;
}
public static Map<String, Integer> getPlayerRanks(String playerName) {
updateLeaderboards();
Map<String, Integer> skills = new HashMap<String, Integer>();
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill()) {
continue;
}
skills.put(skill.name(), getPlayerRank(playerName, playerStatHash.get(skill)));
}
skills.put("ALL", getPlayerRank(playerName, powerLevels));
return skills;
}
public static List<PlayerStat> getPlayerStats(String skillName) {
return (skillName.equalsIgnoreCase("all")) ? powerLevels : playerStatHash.get(SkillType.getSkill(skillName));
}
private static int loadStat(List<PlayerStat> statList, String playerName, String[] data, int dataIndex) {
if (data.length > dataIndex) {
int statValue = Integer.parseInt(data[dataIndex]);
statList.add(new PlayerStat(playerName, statValue));
return statValue;
}
return 0;
}
private static class SkillComparator implements Comparator<PlayerStat> {

View File

@@ -0,0 +1,638 @@
package com.gmail.nossr50.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.DatabaseUpdateType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
import com.gmail.nossr50.util.Misc;
public final class SQLDatabaseManager {
private static String connectionString;
private static String tablePrefix = Config.getInstance().getMySQLTablePrefix();
private static Connection connection = null;
// Scale waiting time by this much per failed attempt
private static final double SCALING_FACTOR = 40;
// Minimum wait in nanoseconds (default 500ms)
private static final long MIN_WAIT = 500L * 1000000L;
// Maximum time to wait between reconnects (default 5 minutes)
private static final long MAX_WAIT = 5L * 60L * 1000L * 1000000L;
// How long to wait when checking if connection is valid (default 3 seconds)
private static final int VALID_TIMEOUT = 3;
// When next to try connecting to Database in nanoseconds
private static long nextReconnectTimestamp = 0L;
// How many connection attempts have failed
private static int reconnectAttempt = 0;
private static final long ONE_MONTH = 2630000000L;
private SQLDatabaseManager() {}
/**
* Attempt to connect to the mySQL database.
*/
public static void connect() {
Config configInstance = Config.getInstance();
connectionString = "jdbc:mysql://" + configInstance.getMySQLServerName() + ":" + configInstance.getMySQLServerPort() + "/" + configInstance.getMySQLDatabaseName();
try {
mcMMO.p.getLogger().info("Attempting connection to MySQL...");
// Force driver to load if not yet loaded
Class.forName("com.mysql.jdbc.Driver");
Properties connectionProperties = new Properties();
connectionProperties.put("user", configInstance.getMySQLUserName());
connectionProperties.put("password", configInstance.getMySQLUserPassword());
connectionProperties.put("autoReconnect", "false");
connectionProperties.put("maxReconnects", "0");
connection = DriverManager.getConnection(connectionString, connectionProperties);
mcMMO.p.getLogger().info("Connection to MySQL was a success!");
}
catch (SQLException ex) {
connection = null;
if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
mcMMO.p.getLogger().info("Connection to MySQL failed!");
}
}
catch (ClassNotFoundException ex) {
connection = null;
if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
mcMMO.p.getLogger().info("MySQL database driver not found!");
}
}
}
/**
* Attempt to create the database structure.
*/
public static void createStructure() {
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ "`user` varchar(40) NOT NULL,"
+ "`lastlogin` int(32) unsigned NOT NULL,"
+ "PRIMARY KEY (`id`),"
+ "UNIQUE KEY `user` (`user`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`hudtype` varchar(50) NOT NULL DEFAULT 'STANDARD',"
+ "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "cooldowns` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "experience` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
checkDatabaseStructure(DatabaseUpdateType.FISHING);
checkDatabaseStructure(DatabaseUpdateType.BLAST_MINING);
checkDatabaseStructure(DatabaseUpdateType.INDEX);
checkDatabaseStructure(DatabaseUpdateType.MOB_HEALTHBARS);
checkDatabaseStructure(DatabaseUpdateType.PARTY_NAMES);
}
/**
* Attempt to write the SQL query.
*
* @param sql Query to write.
* @return true if the query was successfully written, false otherwise.
*/
public static boolean write(String sql) {
if (!checkConnected()) {
return false;
}
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
statement.executeUpdate();
return true;
}
catch (SQLException ex) {
if (!sql.equalsIgnoreCase("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party` ;")) {
printErrors(ex);
}
return false;
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
}
public static boolean removeUserSQL(String playerName) {
return SQLDatabaseManager.update("DELETE FROM u, e, h, s, c " +
"USING " + tablePrefix + "users u " +
"JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
"JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
"JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
"JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
"WHERE u.user = '" + playerName + "'") != 0;
}
/**
* Returns the number of rows affected by either a DELETE or UPDATE query
*
* @param sql SQL query to execute
* @return the number of rows affected
*/
public static int update(String sql) {
if (!checkConnected()) {
return 0;
}
int rows = 0;
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
rows = statement.executeUpdate();
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
return rows;
}
/**
* Get the Integer. Only return first row / first field.
*
* @param sql SQL query to execute
* @return the value in the first row / first field
*/
public static int getInt(String sql) {
if (!checkConnected()) {
return 0;
}
int result = 0;
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
result = resultSet.getInt(1);
}
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
return result;
}
/**
* Check connection status and re-establish if dead or stale.
*
* If the very first immediate attempt fails, further attempts
* will be made in progressively larger intervals up to MAX_WAIT
* intervals.
*
* This allows for MySQL to time out idle connections as needed by
* server operator, without affecting McMMO, while still providing
* protection against a database outage taking down Bukkit's tick
* processing loop due to attemping a database connection each
* time McMMO needs the database.
*
* @return the boolean value for whether or not we are connected
*/
public static boolean checkConnected() {
boolean isClosed = true;
boolean isValid = false;
boolean exists = (connection != null);
// If we're waiting for server to recover then leave early
if (nextReconnectTimestamp > 0 && nextReconnectTimestamp > System.nanoTime()) {
return false;
}
if (exists) {
try {
isClosed = connection.isClosed();
}
catch (SQLException e) {
isClosed = true;
e.printStackTrace();
printErrors(e);
}
if (!isClosed) {
try {
isValid = connection.isValid(VALID_TIMEOUT);
}
catch (SQLException e) {
// Don't print stack trace because it's valid to lose idle connections to the server and have to restart them.
isValid = false;
}
}
}
// Leave if all ok
if (exists && !isClosed && isValid) {
// Housekeeping
nextReconnectTimestamp = 0;
reconnectAttempt = 0;
return true;
}
// Cleanup after ourselves for GC and MySQL's sake
if (exists && !isClosed) {
try {
connection.close();
}
catch (SQLException ex) {
// This is a housekeeping exercise, ignore errors
}
}
// Try to connect again
connect();
// Leave if connection is good
try {
if (connection != null && !connection.isClosed()) {
// Schedule a database save if we really had an outage
if (reconnectAttempt > 1) {
new SQLReconnectTask().runTaskLater(mcMMO.p, 5);
}
nextReconnectTimestamp = 0;
reconnectAttempt = 0;
return true;
}
}
catch (SQLException e) {
// Failed to check isClosed, so presume connection is bad and attempt later
e.printStackTrace();
printErrors(e);
}
reconnectAttempt++;
nextReconnectTimestamp = (long)(System.nanoTime() + Math.min(MAX_WAIT, (reconnectAttempt * SCALING_FACTOR * MIN_WAIT)));
return false;
}
/**
* Read SQL query.
*
* @param sql SQL query to read
* @return the rows in this SQL query
*/
public static HashMap<Integer, ArrayList<String>> read(String sql) {
ResultSet resultSet;
HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
if (checkConnected()) {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
ArrayList<String> column = new ArrayList<String>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
column.add(resultSet.getString(i));
}
rows.put(resultSet.getRow(), column);
}
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
printErrors(e);
}
}
}
}
return rows;
}
public static Map<String, Integer> readSQLRank(String playerName) {
ResultSet resultSet;
Map<String, Integer> skills = new HashMap<String, Integer>();
if (checkConnected()) {
try {
for (SkillType skillType : SkillType.values()) {
if (skillType.isChildSkill()) {
continue;
}
String skillName = skillType.name().toLowerCase();
String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
"AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
resultSet.next();
int rank = resultSet.getInt("rank");
sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
"AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = '" + playerName + "') ORDER BY user";
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
skills.put(skillType.name(), rank + resultSet.getRow());
break;
}
}
statement.close();
}
String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
"AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > " +
"(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
resultSet.next();
int rank = resultSet.getInt("rank");
sql = "SELECT user, taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
"AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing = " +
"(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
resultSet = statement.executeQuery();
while (resultSet.next()) {
if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
skills.put("ALL", rank + resultSet.getRow());
break;
}
}
statement.close();
}
catch (SQLException ex) {
printErrors(ex);
}
}
return skills;
}
public static int purgePowerlessSQL() {
HashMap<Integer, ArrayList<String>> usernames = read("SELECT u.user FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u WHERE s.user_id = u.id AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0");
write("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " +
"JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
"JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
"JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
"JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
"WHERE (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0");
return processPurge(usernames.values());
}
public static int purgeOldSQL() {
long currentTime = System.currentTimeMillis();
long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
HashMap<Integer, ArrayList<String>> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")");
write("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " +
"JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
"JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
"JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
"JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
"WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")");
return processPurge(usernames.values());
}
private static int processPurge(Collection<ArrayList<String>> usernames) {
int purgedUsers = 0;
for (ArrayList<String> user : usernames) {
Misc.profileCleanup(user.get(0));
purgedUsers++;
}
return purgedUsers;
}
/**
* Check database structure for missing values.
*
* @param update Type of data to check updates for
*/
private static void checkDatabaseStructure(DatabaseUpdateType update) {
String sql = null;
ResultSet resultSet = null;
HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
switch (update) {
case BLAST_MINING:
sql = "SELECT * FROM `" + tablePrefix + "cooldowns` ORDER BY `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30";
break;
case FISHING:
sql = "SELECT * FROM `" + tablePrefix + "experience` ORDER BY `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30";
break;
case INDEX:
if (read("SHOW INDEX FROM " + tablePrefix + "skills").size() != 13 && checkConnected()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
write("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_taming` (`taming`) USING BTREE, "
+ "ADD INDEX `idx_mining` (`mining`) USING BTREE, "
+ "ADD INDEX `idx_woodcutting` (`woodcutting`) USING BTREE, "
+ "ADD INDEX `idx_repair` (`repair`) USING BTREE, "
+ "ADD INDEX `idx_unarmed` (`unarmed`) USING BTREE, "
+ "ADD INDEX `idx_herbalism` (`herbalism`) USING BTREE, "
+ "ADD INDEX `idx_excavation` (`excavation`) USING BTREE, "
+ "ADD INDEX `idx_archery` (`archery`) USING BTREE, "
+ "ADD INDEX `idx_swords` (`swords`) USING BTREE, "
+ "ADD INDEX `idx_axes` (`axes`) USING BTREE, "
+ "ADD INDEX `idx_acrobatics` (`acrobatics`) USING BTREE, "
+ "ADD INDEX `idx_fishing` (`fishing`) USING BTREE;");
}
break;
case MOB_HEALTHBARS:
sql = "SELECT * FROM `" + tablePrefix + "huds` ORDER BY `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30";
break;
case PARTY_NAMES:
write("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party` ;");
break;
default:
break;
}
PreparedStatement statement = null;
try {
if (!checkConnected()) {
return;
}
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
ArrayList<String> column = new ArrayList<String>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
column.add(resultSet.getString(i));
}
rows.put(resultSet.getRow(), column);
}
}
catch (SQLException ex) {
switch (update) {
case BLAST_MINING:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
write("ALTER TABLE `"+tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' ;");
break;
case FISHING:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
write("ALTER TABLE `"+tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
write("ALTER TABLE `"+tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
break;
case MOB_HEALTHBARS:
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
write("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "' ;");
break;
default:
break;
}
}
finally {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
// Ignore the error, we're leaving
}
}
}
}
private static void printErrors(SQLException ex) {
mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
}
}

View File

@@ -3,7 +3,7 @@ package com.gmail.nossr50.datatypes.database;
public enum DatabaseUpdateType {
FISHING,
BLAST_MINING,
CASCADE_DELETE,
INDEX,
MOB_HEALTHBARS;
MOB_HEALTHBARS,
PARTY_NAMES,
}

View File

@@ -0,0 +1,33 @@
package com.gmail.nossr50.datatypes.party;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.util.ItemUtils;
public enum ItemShareType {
LOOT,
MINING,
HERBALISM,
WOODCUTTING,
MISC;
public static ItemShareType getShareType(ItemStack itemStack) {
if (ItemUtils.isMobDrop(itemStack)) {
return LOOT;
}
else if (ItemUtils.isMiningDrop(itemStack)) {
return MINING;
}
else if (ItemUtils.isHerbalismDrop(itemStack)) {
return HERBALISM;
}
else if (ItemUtils.isWoodcuttingDrop(itemStack)) {
return WOODCUTTING;
}
else if (ItemUtils.isMiscDrop(itemStack)) {
return MISC;
}
return null;
}
}

View File

@@ -1,36 +1,41 @@
package com.gmail.nossr50.datatypes.party;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.gmail.nossr50.party.ShareHandler;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.ShareHandler.ShareMode;
public class Party {
private List<OfflinePlayer> members = new ArrayList<OfflinePlayer>();
private LinkedHashSet<String> members = new LinkedHashSet<String>();
private String leader;
private String name;
private String password;
private boolean locked;
private ShareHandler.ShareMode xpShareMode = ShareHandler.ShareMode.NONE;
private ShareHandler.ShareMode itemShareMode = ShareHandler.ShareMode.NONE;
private ShareMode xpShareMode = ShareMode.NONE;
private ShareMode itemShareMode = ShareMode.NONE;
private boolean shareLootDrops = true;
private boolean shareMiningDrops = true;
private boolean shareHerbalismDrops = true;
private boolean shareWoodcuttingDrops = true;
private boolean shareMiscDrops = true;
public List<OfflinePlayer> getMembers() {
public LinkedHashSet<String> getMembers() {
return members;
}
public List<Player> getOnlineMembers() {
List<Player> onlineMembers = new ArrayList<Player>();
for (OfflinePlayer member : members) {
for (String memberName : members) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberName);
if (member.isOnline()) {
onlineMembers.add(member.getPlayer());
}
@@ -55,40 +60,27 @@ public class Party {
return locked;
}
public boolean sharingLootDrops() {
return shareLootDrops;
}
public boolean sharingMiningDrops() {
return shareMiningDrops;
}
public boolean sharingHerbalismDrops() {
return shareHerbalismDrops;
}
public boolean sharingWoodcuttingDrops() {
return shareWoodcuttingDrops;
}
public List<String> getItemShareCategories() {
List<String> shareCategories = new ArrayList<String>();
// TODO Locale the category names!
if (sharingLootDrops()) {
shareCategories.add("Loot");
if (shareLootDrops) {
shareCategories.add(LocaleLoader.getString("Party.ItemShare.Category.Loot"));
}
if (sharingMiningDrops()) {
shareCategories.add("Mining");
if (shareMiningDrops) {
shareCategories.add(LocaleLoader.getString("Party.ItemShare.Category.Mining"));
}
if (sharingHerbalismDrops()) {
shareCategories.add("Herbalism");
if (shareHerbalismDrops) {
shareCategories.add(LocaleLoader.getString("Party.ItemShare.Category.Herbalism"));
}
if (sharingWoodcuttingDrops()) {
shareCategories.add("Woodcutting");
if (shareWoodcuttingDrops) {
shareCategories.add(LocaleLoader.getString("Party.ItemShare.Category.Woodcutting"));
}
if (shareMiscDrops) {
shareCategories.add(LocaleLoader.getString("Party.ItemShare.Category.Misc"));
}
return shareCategories;
@@ -110,35 +102,68 @@ public class Party {
this.locked = locked;
}
public void setXpShareMode(ShareHandler.ShareMode xpShareMode) {
public void setXpShareMode(ShareMode xpShareMode) {
this.xpShareMode = xpShareMode;
}
public ShareHandler.ShareMode getXpShareMode() {
public ShareMode getXpShareMode() {
return xpShareMode;
}
public void setItemShareMode(ShareHandler.ShareMode itemShareMode) {
public void setItemShareMode(ShareMode itemShareMode) {
this.itemShareMode = itemShareMode;
}
public ShareHandler.ShareMode getItemShareMode() {
public ShareMode getItemShareMode() {
return itemShareMode;
}
public void setSharingLootDrops(boolean enabled) {
shareLootDrops = enabled;
public boolean sharingDrops(ItemShareType shareType) {
switch (shareType) {
case HERBALISM:
return shareHerbalismDrops;
case LOOT:
return shareLootDrops;
case MINING:
return shareMiningDrops;
case MISC:
return shareMiscDrops;
case WOODCUTTING:
return shareWoodcuttingDrops;
default:
return false;
}
}
public void setSharingMiningDrops(boolean enabled) {
shareMiningDrops = enabled;
}
public void setSharingDrops(ItemShareType shareType, boolean enabled) {
switch (shareType) {
case HERBALISM:
shareHerbalismDrops = enabled;
break;
public void setSharingHerbalismDrops(boolean enabled) {
shareHerbalismDrops = enabled;
}
case LOOT:
shareLootDrops = enabled;
break;
public void setSharingWoodcuttingDrops(boolean enabled) {
shareWoodcuttingDrops = enabled;
case MINING:
shareMiningDrops = enabled;
break;
case MISC:
shareMiscDrops = enabled;
break;
case WOODCUTTING:
shareWoodcuttingDrops = enabled;
break;
default:
return;
}
}
}

View File

@@ -20,6 +20,7 @@ import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
import com.gmail.nossr50.events.experience.McMMOPlayerXpGainEvent;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.party.ShareHandler;
import com.gmail.nossr50.runnables.skills.AbilityDisableTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
import com.gmail.nossr50.skills.archery.ArcheryManager;
@@ -70,7 +71,9 @@ public class McMMOPlayer {
private boolean abilityUse = true;
private boolean placedRepairAnvil;
private int lastRepairClick;
private boolean placedSalvageAnvil;
private int lastSalvageClick;
private boolean godMode;
private Map<AbilityType, Boolean> abilityMode = new HashMap<AbilityType, Boolean>();
@@ -180,7 +183,8 @@ public class McMMOPlayer {
*/
public void resetAbilityMode() {
for (AbilityType ability : AbilityType.values()) {
setAbilityMode(ability, false);
// Correctly disable and handle any special deactivate code
new AbilityDisableTask(this, ability).run();
}
}
@@ -369,6 +373,42 @@ public class McMMOPlayer {
}
}
/*
* Repair Anvil Usage
*/
public int getLastAnvilUse(int anvilId) {
if (anvilId == Repair.repairAnvilId) {
return lastRepairClick;
}
if (anvilId == Repair.salvageAnvilId) {
return lastSalvageClick;
}
return 0;
}
public void setLastAnvilUse(int anvilId, int value) {
if (anvilId == Repair.repairAnvilId) {
lastRepairClick = value;
}
if (anvilId == Repair.salvageAnvilId) {
lastSalvageClick = value;
}
}
public void actualizeLastAnvilUse(int anvilId) {
if (anvilId == Repair.repairAnvilId) {
lastRepairClick = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
}
if (anvilId == Repair.salvageAnvilId) {
lastSalvageClick = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
}
}
/*
* God Mode
*/
@@ -420,7 +460,7 @@ public class McMMOPlayer {
* @param skillType Skill being used
* @param xp Experience amount to process
*/
public void beginXpGain(SkillType skillType, int xp) {
public void beginXpGain(SkillType skillType, float xp) {
if (xp == 0) {
return;
}
@@ -451,7 +491,7 @@ public class McMMOPlayer {
* @param skillType Skill being used
* @param xp Experience amount to process
*/
public void beginUnsharedXpGain(SkillType skillType, int xp) {
public void beginUnsharedXpGain(SkillType skillType, float xp) {
xp = modifyXpGain(skillType, xp);
applyXpGain(skillType, xp);
@@ -463,19 +503,20 @@ public class McMMOPlayer {
* @param skillType Skill being used
* @param xp Experience amount to add
*/
public void applyXpGain(SkillType skillType, int xp) {
public void applyXpGain(SkillType skillType, float xp) {
if (skillType.isChildSkill()) {
Set<SkillType> parentSkills = FamilyTree.getParents(skillType);
for (SkillType parentSkill : parentSkills) {
if (Permissions.skillEnabled(player, parentSkill)) {
applyXpGain(parentSkill, xp / parentSkills.size());
}
applyXpGain(parentSkill, xp / parentSkills.size());
}
return;
}
if (!Permissions.skillEnabled(player, skillType)) {
return;
}
McMMOPlayerXpGainEvent event = new McMMOPlayerXpGainEvent(player, skillType, xp);
mcMMO.p.getServer().getPluginManager().callEvent(event);
@@ -484,7 +525,7 @@ public class McMMOPlayer {
return;
}
profile.setSkillXpLevel(skillType, profile.getSkillXpLevel(skillType) + event.getXpGained());
profile.setSkillXpLevel(skillType, profile.getSkillXpLevelRaw(skillType) + event.getRawXpGained());
McMMOHud spoutHud = profile.getSpoutHud();
@@ -655,12 +696,12 @@ public class McMMOPlayer {
* @param xp Experience amount to process
* @return Modified experience
*/
private int modifyXpGain(SkillType skillType, int xp) {
private float modifyXpGain(SkillType skillType, float xp) {
if (player.getGameMode() == GameMode.CREATIVE || (skillType.getMaxLevel() < profile.getSkillLevel(skillType) + 1) || (Config.getInstance().getPowerLevelCap() < getPowerLevel() + 1)) {
return 0;
}
xp = (int) (xp / skillType.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier());
xp = (float) (xp / skillType.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier());
if (Config.getInstance().getToolModsEnabled()) {
ItemStack item = player.getItemInHand();

View File

@@ -144,4 +144,14 @@ public enum SkillType {
public Color getRunescapeModeColor() {
return runescapeColor;
}
public static SkillType byAbility(AbilityType ability) {
for (SkillType type : values()) {
if (type.getAbility() == ability) {
return type;
}
}
return null;
}
}

View File

@@ -8,9 +8,9 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
* Called when a player gains XP in a skill
*/
public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
private int xpGained;
private float xpGained;
public McMMOPlayerXpGainEvent(Player player, SkillType skill, int xpGained) {
public McMMOPlayerXpGainEvent(Player player, SkillType skill, float xpGained) {
super(player, skill);
this.xpGained = xpGained;
}
@@ -18,13 +18,29 @@ public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
/**
* @return The amount of experience gained in this event
*/
public int getXpGained() {
public float getRawXpGained() {
return xpGained;
}
/**
* @param xpGained int amount of experience gained in this event
*/
@Deprecated
public int getXpGained() {
return (int) xpGained;
}
/**
* @param xpGained int amount of experience gained in this event
*/
public void setRawXpGained(float xpGained) {
this.xpGained = xpGained;
}
/**
* @param xpGained int amount of experience gained in this event
*/
@Deprecated
public void setXpGained(int xpGained) {
this.xpGained = xpGained;
}

View File

@@ -0,0 +1,12 @@
package com.gmail.nossr50.events.fake;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerFishEvent;
public class FakePlayerFishEvent extends PlayerFishEvent {
public FakePlayerFishEvent(Player player, Entity entity, Fish hookEntity, State state) {
super(player, entity, hookEntity, state);
}
}

View File

@@ -0,0 +1,35 @@
package com.gmail.nossr50.events.skills.abilities;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
public class McMMOPlayerAbilityActivateEvent extends McMMOPlayerSkillEvent implements Cancellable {
private AbilityType abilityType;
private boolean cancelled;
public McMMOPlayerAbilityActivateEvent(Player player, SkillType skill) {
super(player, skill);
abilityType = skill.getAbility();
cancelled = false;
}
/**
* @return The ability type involved in this event
*/
public AbilityType getAbilityType() {
return abilityType;
}
public boolean isCancelled() {
return cancelled;
}
public void setCancelled(boolean value) {
this.cancelled = value;
}
}

View File

@@ -0,0 +1,22 @@
package com.gmail.nossr50.events.skills.abilities;
import org.bukkit.entity.Player;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
public class McMMOPlayerAbilityDeactivateEvent extends McMMOPlayerSkillEvent {
private AbilityType ability;
public McMMOPlayerAbilityDeactivateEvent(Player player, SkillType skill) {
super(player, skill);
this.ability = skill.getAbility();
}
public AbilityType getAbility() {
return ability;
}
}

View File

@@ -63,17 +63,17 @@ public class BlockListener implements Listener {
Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished
for (Block b : blocks) {
if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.placeStore.isTrue(b)) {
if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.getPlaceStore().isTrue(b)) {
b.getRelative(direction).setMetadata(mcMMO.blockMetadataKey, mcMMO.metadataValue);
if (b.equals(futureEmptyBlock)) {
mcMMO.placeStore.setFalse(b);
mcMMO.getPlaceStore().setFalse(b);
}
}
}
for (Block b : blocks) {
if (b.getRelative(direction).hasMetadata(mcMMO.blockMetadataKey)) {
mcMMO.placeStore.setTrue(b.getRelative(direction));
mcMMO.getPlaceStore().setTrue(b.getRelative(direction));
b.getRelative(direction).removeMetadata(mcMMO.blockMetadataKey, plugin);
}
}
@@ -110,7 +110,7 @@ public class BlockListener implements Listener {
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
if (BlockUtils.shouldBeWatched(blockState)) {
mcMMO.placeStore.setTrue(blockState);
mcMMO.getPlaceStore().setTrue(blockState);
}
if (Repair.anvilMessagesEnabled && (blockId == Repair.repairAnvilId || blockId == Repair.salvageAnvilId)) {
@@ -163,13 +163,13 @@ public class BlockListener implements Listener {
}
/* MINING */
else if (BlockUtils.affectedBySuperBreaker(blockState) && ItemUtils.isPickaxe(heldItem) && Permissions.skillEnabled(player, SkillType.MINING) && !mcMMO.placeStore.isTrue(blockState)) {
else if (BlockUtils.affectedBySuperBreaker(blockState) && ItemUtils.isPickaxe(heldItem) && Permissions.skillEnabled(player, SkillType.MINING) && !mcMMO.getPlaceStore().isTrue(blockState)) {
MiningManager miningManager = mcMMOPlayer.getMiningManager();
miningManager.miningBlockCheck(blockState);
}
/* WOOD CUTTING */
else if (BlockUtils.isLog(blockState) && Permissions.skillEnabled(player, SkillType.WOODCUTTING) && !mcMMO.placeStore.isTrue(blockState)) {
else if (BlockUtils.isLog(blockState) && Permissions.skillEnabled(player, SkillType.WOODCUTTING) && !mcMMO.getPlaceStore().isTrue(blockState)) {
WoodcuttingManager woodcuttingManager = mcMMOPlayer.getWoodcuttingManager();
if (woodcuttingManager.canUseTreeFeller(heldItem)) {
@@ -181,7 +181,7 @@ public class BlockListener implements Listener {
}
/* EXCAVATION */
else if (BlockUtils.affectedByGigaDrillBreaker(blockState) && ItemUtils.isShovel(heldItem) && Permissions.skillEnabled(player, SkillType.EXCAVATION) && !mcMMO.placeStore.isTrue(blockState)) {
else if (BlockUtils.affectedByGigaDrillBreaker(blockState) && ItemUtils.isShovel(heldItem) && Permissions.skillEnabled(player, SkillType.EXCAVATION) && !mcMMO.getPlaceStore().isTrue(blockState)) {
ExcavationManager excavationManager = mcMMOPlayer.getExcavationManager();
excavationManager.excavationBlockCheck(blockState);
@@ -191,7 +191,7 @@ public class BlockListener implements Listener {
}
/* Remove metadata from placed watched blocks */
mcMMO.placeStore.setFalse(blockState);
mcMMO.getPlaceStore().setFalse(blockState);
}
/**
@@ -298,7 +298,7 @@ public class BlockListener implements Listener {
* We don't need to check permissions here because they've already been checked for the ability to even activate.
*/
if (mcMMOPlayer.getAbilityMode(AbilityType.TREE_FELLER) && BlockUtils.isLog(blockState)) {
player.playSound(blockState.getLocation(), Sound.FIZZ, Misc.FIZZ_VOLUME, Misc.FIZZ_PITCH);
player.playSound(blockState.getLocation(), Sound.FIZZ, Misc.FIZZ_VOLUME, Misc.getFizzPitch());
}
}
@@ -341,7 +341,7 @@ public class BlockListener implements Listener {
plugin.getServer().getPluginManager().callEvent(new FakePlayerAnimationEvent(player));
event.setInstaBreak(true);
player.playSound(block.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
player.playSound(block.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.getPopPitch());
}
}
// Another perm check for the cracked blocks activation
@@ -356,7 +356,7 @@ public class BlockListener implements Listener {
else if (BlockUtils.isLeaves(blockState)) {
if (mcMMOPlayer.getWoodcuttingManager().canUseLeafBlower(heldItem) && SkillUtils.blockBreakSimulate(block, player, true)) {
event.setInstaBreak(true);
player.playSound(blockState.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
player.playSound(blockState.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.getPopPitch());
}
}
}

View File

@@ -2,7 +2,9 @@ package com.gmail.nossr50.listeners;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
@@ -15,19 +17,22 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
@@ -52,6 +57,24 @@ public class EntityListener implements Listener {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onEntityShootBow(EntityShootBowEvent event) {
ItemStack bow = event.getBow();
if (bow != null) {
Entity projectile = event.getProjectile();
if (projectile instanceof Arrow) {
if (bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
projectile.setMetadata(mcMMO.infiniteArrowKey, mcMMO.metadataValue);
}
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(plugin, Math.min(event.getForce() * AdvancedConfig.getInstance().getForceMultiplier(), 1.0)));
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, Archery.locationToString(projectile.getLocation())));
}
}
}
/**
* Monitor EntityChangeBlock events.
*
@@ -68,12 +91,12 @@ public class EntityListener implements Listener {
Block block = event.getBlock();
boolean isTracked = entity.hasMetadata(mcMMO.entityMetadataKey);
if (mcMMO.placeStore.isTrue(block) && !isTracked) {
mcMMO.placeStore.setFalse(block);
if (mcMMO.getPlaceStore().isTrue(block) && !isTracked) {
mcMMO.getPlaceStore().setFalse(block);
entity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
}
else if (isTracked) {
mcMMO.placeStore.setTrue(block);
mcMMO.getPlaceStore().setTrue(block);
}
}
@@ -298,14 +321,21 @@ public class EntityListener implements Listener {
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCreatureSpawn(CreatureSpawnEvent event) {
if (Misc.isSpawnerXPEnabled) {
return;
}
switch (event.getSpawnReason()) {
case SPAWNER:
case SPAWNER_EGG:
LivingEntity entity = event.getEntity();
Entity passenger = entity.getPassenger();
SpawnReason reason = event.getSpawnReason();
entity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
if (reason == SpawnReason.SPAWNER || reason == SpawnReason.SPAWNER_EGG) {
event.getEntity().setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
if (passenger != null) {
passenger.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
}
return;
default:
return;
}
}

View File

@@ -1,5 +1,8 @@
package com.gmail.nossr50.listeners;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Furnace;
@@ -19,8 +22,10 @@ import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.skills.smelting.SmeltingManager;
import com.gmail.nossr50.util.ItemUtils;
@@ -96,10 +101,11 @@ public class InventoryListener implements Listener {
if (furnaceState instanceof Furnace) {
ItemStack smelting = ((Furnace) furnaceState).getInventory().getSmelting();
List<MetadataValue> metadata = furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey);
if (furnaceBlock.hasMetadata(mcMMO.furnaceMetadataKey) && smelting != null && ItemUtils.isSmeltable(smelting)) {
if (!metadata.isEmpty() && smelting != null && ItemUtils.isSmeltable(smelting)) {
// We can make this assumption because we (should) be the only ones using this exact metadata
Player player = plugin.getServer().getPlayer(furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey).get(0).asString());
Player player = plugin.getServer().getPlayer(metadata.get(0).asString());
if (Misc.isNPCEntity(player) || !Permissions.fuelEfficiency(player)) {
return;
@@ -117,10 +123,19 @@ public class InventoryListener implements Listener {
if (furnaceState instanceof Furnace) {
ItemStack smelting = ((Furnace) furnaceState).getInventory().getSmelting();
List<MetadataValue> metadata = furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey);
if (furnaceBlock.hasMetadata(mcMMO.furnaceMetadataKey) && smelting != null && ItemUtils.isSmeltable(smelting)) {
if (Config.getInstance().getPotatoEnabled() && smelting.getType() == Material.POTATO_ITEM) {
if ((Config.getInstance().getPotatoChance() / 100.0) >= Misc.getRandom().nextDouble()) {
event.setCancelled(true);
furnaceState.getWorld().createExplosion(furnaceState.getLocation(), 4F, true);
return;
}
}
if (!metadata.isEmpty() && smelting != null && ItemUtils.isSmeltable(smelting)) {
// We can make this assumption because we (should) be the only ones using this exact metadata
Player player = plugin.getServer().getPlayer(furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey).get(0).asString());
Player player = plugin.getServer().getPlayer(metadata.get(0).asString());
if (Misc.isNPCEntity(player) || !Permissions.skillEnabled(player, SkillType.SMELTING)) {
return;
@@ -138,10 +153,11 @@ public class InventoryListener implements Listener {
if (furnaceState instanceof Furnace) {
ItemStack result = ((Furnace) furnaceState).getInventory().getResult();
List<MetadataValue> metadata = furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey);
if (furnaceBlock.hasMetadata(mcMMO.furnaceMetadataKey) && result != null && ItemUtils.isSmelted(result)) {
if (!metadata.isEmpty() && result != null && ItemUtils.isSmelted(result)) {
// We can make this assumption because we (should) be the only ones using this exact metadata
Player player = plugin.getServer().getPlayer(furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey).get(0).asString());
Player player = plugin.getServer().getPlayer(metadata.get(0).asString());
if (Misc.isNPCEntity(player)) {
return;
@@ -163,26 +179,18 @@ public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCraftItem(CraftItemEvent event) {
if (event.getRecipe().getResult() == null) {
return;
}
else if (!ItemUtils.isMcMMOItem(event.getRecipe().getResult())) {
return;
}
else if (event.getWhoClicked() == null) {
return;
}
else if (!(event.getWhoClicked() instanceof Player)) {
ItemStack result = event.getRecipe().getResult();
final HumanEntity whoClicked = event.getWhoClicked();
if (!ItemUtils.isMcMMOItem(result) || Misc.isNPCEntity(whoClicked) || !(whoClicked instanceof Player)) {
return;
}
final Player player = (Player) event.getWhoClicked();
mcMMO.p.getServer().getScheduler().scheduleSyncDelayedTask(mcMMO.p, new Runnable() {
mcMMO.p.getServer().getScheduler().runTaskLater(mcMMO.p, new Runnable() {
@Override
public void run() {
player.updateInventory();
((Player) whoClicked).updateInventory();
}
});
}, 0);
}
}

View File

@@ -2,9 +2,11 @@ package com.gmail.nossr50.listeners;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -40,6 +42,7 @@ import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.repair.RepairManager;
import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.Unarmed;
import com.gmail.nossr50.util.BlockUtils;
@@ -47,9 +50,11 @@ import com.gmail.nossr50.util.ChimaeraWing;
import com.gmail.nossr50.util.HardcoreManager;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.MobHealthbarUtils;
import com.gmail.nossr50.util.Motd;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.SkillUtils;
public class PlayerListener implements Listener {
@@ -64,11 +69,10 @@ public class PlayerListener implements Listener {
String deathMessage = event.getDeathMessage();
if (deathMessage == null) {
mcMMO.p.getLogger().severe("You have another plugin causing null death messages. mcMMO cannot process this death message.");
return;
}
event.setDeathMessage(deathMessage.replaceAll("(?:\u00A7(?:[0-9A-FK-ORa-fk-or]){1}(?:[\u2764\u25A0]{1,10})){1,2}", "a mob"));
event.setDeathMessage(MobHealthbarUtils.fixDeathMessage(deathMessage, event.getEntity()));
}
/**
@@ -77,26 +81,24 @@ public class PlayerListener implements Listener {
* @param event The event to watch
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerDeath(PlayerDeathEvent event) {
public void onPlayerDeathMonitor(PlayerDeathEvent event) {
if (!Config.getInstance().getHardcoreEnabled()) {
return;
}
Player player = event.getEntity();
if (Misc.isNPCEntity(player)) {
if (Misc.isNPCEntity(player) || Permissions.hardcoreBypass(player)) {
return;
}
if (!Permissions.hardcoreBypass(player)) {
Player killer = player.getKiller();
Player killer = player.getKiller();
if (killer != null && Config.getInstance().getHardcoreVampirismEnabled()) {
HardcoreManager.invokeVampirism(killer, player);
}
HardcoreManager.invokeStatPenalty(player);
if (killer != null && Config.getInstance().getHardcoreVampirismEnabled()) {
HardcoreManager.invokeVampirism(killer, player);
}
HardcoreManager.invokeStatPenalty(player);
}
/**
@@ -105,7 +107,7 @@ public class PlayerListener implements Listener {
* @param event The event to watch
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerWorldChangeEvent(PlayerChangedWorldEvent event) {
public void onPlayerWorldChange(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
if (Misc.isNPCEntity(player)) {
@@ -131,16 +133,19 @@ public class PlayerListener implements Listener {
* @param event The event to watch
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerLoginEvent(PlayerLoginEvent event) {
if (event.getResult() == Result.ALLOWED) {
Player player = event.getPlayer();
if (Misc.isNPCEntity(player)) {
return;
}
UserManager.addUser(player).actualizeRespawnATS();
public void onPlayerLogin(PlayerLoginEvent event) {
if (event.getResult() != Result.ALLOWED) {
return;
}
Player player = event.getPlayer();
if (Misc.isNPCEntity(player)) {
return;
}
UserManager.addUser(player).actualizeRespawnATS();
ScoreboardManager.enablePowerLevelDisplay(player);
}
/**
@@ -149,16 +154,11 @@ public class PlayerListener implements Listener {
* @param event The event to modify
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerDropItemEvent(PlayerDropItemEvent event) {
Player player = event.getPlayer();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
public void onPlayerDropItem(PlayerDropItemEvent event) {
Item drop = event.getItemDrop();
if (mcMMOPlayer.getAbilityMode(AbilityType.GIGA_DRILL_BREAKER) || mcMMOPlayer.getAbilityMode(AbilityType.SUPER_BREAKER)) {
event.setCancelled(true);
return;
}
SkillUtils.removeAbilityBuff(event.getItemDrop().getItemStack());
drop.setMetadata(mcMMO.droppedItemKey, mcMMO.metadataValue);
SkillUtils.removeAbilityBuff(drop.getItemStack());
}
/**
@@ -178,6 +178,14 @@ public class PlayerListener implements Listener {
switch (event.getState()) {
case FISHING:
if (!Permissions.krakenBypass(player)) {
event.setCancelled(fishingManager.exploitPrevention());
}
if (event.isCancelled()) {
return;
}
if (fishingManager.canMasterAngler()) {
fishingManager.masterAngler(event.getHook());
}
@@ -197,8 +205,18 @@ public class PlayerListener implements Listener {
if (fishingManager.canShake(entity)) {
fishingManager.shakeCheck((LivingEntity) entity);
}
break;
case IN_GROUND:
Fish hook = event.getHook();
Block block = hook.getLocation().getBlock();
if (fishingManager.canIceFish(block)) {
event.setCancelled(true);
fishingManager.iceFishing(hook, block);
}
break;
default:
break;
}
@@ -212,27 +230,29 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
Player player = event.getPlayer();
Item drop = event.getItem();
ItemStack dropStack = drop.getItemStack();
if (Misc.isNPCEntity(player)) {
return;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
Item drop = event.getItem();
ItemStack dropStack = drop.getItemStack();
if (mcMMOPlayer.inParty() && ItemUtils.isShareable(dropStack)) {
if (!drop.hasMetadata(mcMMO.droppedItemKey) && mcMMOPlayer.inParty() && ItemUtils.isShareable(dropStack)) {
event.setCancelled(ShareHandler.handleItemShare(drop, mcMMOPlayer));
if (event.isCancelled()) {
player.playSound(player.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.getPopPitch());
return;
}
}
if (mcMMOPlayer.isUsingUnarmed() && ItemUtils.isShareable(dropStack)) {
if ((mcMMOPlayer.isUsingUnarmed() && ItemUtils.isShareable(dropStack)) || mcMMOPlayer.getAbilityMode(AbilityType.BERSERK)) {
event.setCancelled(Unarmed.handleItemPickup(player.getInventory(), drop));
if (event.isCancelled()) {
player.playSound(player.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.getPopPitch());
player.updateInventory();
return;
}
@@ -252,10 +272,6 @@ public class PlayerListener implements Listener {
return;
}
if (UserManager.getPlayer(player).getAbilityMode(AbilityType.BERSERK)) {
player.setCanPickupItems(true);
}
/* GARBAGE COLLECTION */
BleedTimerTask.bleedOut(player); // Bleed it out
}
@@ -269,10 +285,6 @@ public class PlayerListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (UserManager.getPlayer(player).getAbilityMode(AbilityType.BERSERK)) {
player.setCanPickupItems(false);
}
if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
Motd.displayAll(player);
}
@@ -281,7 +293,7 @@ public class PlayerListener implements Listener {
player.sendMessage(LocaleLoader.getString("XPRate.Event", Config.getInstance().getExperienceGainsGlobalMultiplier()));
}
if (Permissions.updateNotifications(player) && mcMMO.p.updateAvailable) {
if (Permissions.updateNotifications(player) && plugin.isUpdateAvailable()) {
player.sendMessage(LocaleLoader.getString("UpdateChecker.outdated"));
player.sendMessage(LocaleLoader.getString("UpdateChecker.newavailable"));
}
@@ -311,14 +323,20 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerInteractLowest(PlayerInteractEvent event) {
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (Misc.isNPCEntity(player) || player.getGameMode() == GameMode.CREATIVE) {
return;
}
Block block = event.getClickedBlock();
ItemStack heldItem = player.getItemInHand();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
// This shouldn't be possible - this is probably a band-aid for a larger issue somewhere else.
if (mcMMOPlayer == null) {
return;
}
MiningManager miningManager = mcMMOPlayer.getMiningManager();
switch (event.getAction()) {
@@ -326,16 +344,26 @@ public class PlayerListener implements Listener {
int blockID = block.getTypeId();
/* REPAIR CHECKS */
if (blockID == Repair.repairAnvilId && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.repairableManager.isRepairable(heldItem)) {
UserManager.getPlayer(player).getRepairManager().handleRepair(heldItem);
if (blockID == Repair.repairAnvilId && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
RepairManager repairManager = mcMMOPlayer.getRepairManager();
event.setCancelled(true);
player.updateInventory();
// Make sure the player knows what he's doing when trying to repair an enchanted item
if (!(heldItem.getEnchantments().size() > 0) || repairManager.checkConfirmation(blockID, true)) {
repairManager.handleRepair(heldItem);
player.updateInventory();
}
}
/* SALVAGE CHECKS */
else if (blockID == Repair.salvageAnvilId && Permissions.salvage(player) && Repair.isSalvageable(heldItem)) {
UserManager.getPlayer(player).getRepairManager().handleSalvage(block.getLocation(), heldItem);
RepairManager repairManager = mcMMOPlayer.getRepairManager();
event.setCancelled(true);
player.updateInventory();
// Make sure the player knows what he's doing when trying to salvage an enchanted item
if (!(heldItem.getEnchantments().size() > 0) || repairManager.checkConfirmation(blockID, true)) {
repairManager.handleSalvage(block.getLocation(), heldItem);
player.updateInventory();
}
}
/* BLAST MINING CHECK */
else if (miningManager.canDetonate()) {
@@ -349,6 +377,32 @@ public class PlayerListener implements Listener {
break;
case LEFT_CLICK_BLOCK:
blockID = block.getTypeId();
/* REPAIR CHECKS */
if (blockID == Repair.repairAnvilId && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
RepairManager repairManager = mcMMOPlayer.getRepairManager();
// Cancel repairing an enchanted item
if (repairManager.checkConfirmation(blockID, false) && Config.getInstance().getRepairConfirmRequired()) {
mcMMOPlayer.setLastAnvilUse(Repair.repairAnvilId, 0);
player.sendMessage(LocaleLoader.getString("Skills.Cancelled", LocaleLoader.getString("Repair.Pretty.Name")));
}
}
/* SALVAGE CHECKS */
else if (blockID == Repair.salvageAnvilId && Permissions.salvage(player) && Repair.isSalvageable(heldItem)) {
RepairManager repairManager = mcMMOPlayer.getRepairManager();
// Cancel salvaging an enchanted item
if (repairManager.checkConfirmation(blockID, false) && Config.getInstance().getRepairConfirmRequired()) {
mcMMOPlayer.setLastAnvilUse(Repair.salvageAnvilId, 0);
player.sendMessage(LocaleLoader.getString("Skills.Cancelled", LocaleLoader.getString("Salvage.Pretty.Name")));
}
}
break;
case RIGHT_CLICK_AIR:
/* BLAST MINING CHECK */
if (miningManager.canDetonate()) {
@@ -378,6 +432,11 @@ public class PlayerListener implements Listener {
ItemStack heldItem = player.getItemInHand();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
// This shouldn't be possible - this is probably a band-aid for a larger issue somewhere else.
if (mcMMOPlayer == null) {
return;
}
switch (event.getAction()) {
case RIGHT_CLICK_BLOCK:
Block block = event.getClickedBlock();
@@ -474,22 +533,27 @@ public class PlayerListener implements Listener {
return;
}
boolean isAsync = event.isAsynchronous();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (mcMMOPlayer == null) {
mcMMO.p.debug(player.getName() + " is currently chatting, but has never logged on to the server.");
return;
}
if (mcMMOPlayer.getPartyChatMode()) {
Party party = mcMMOPlayer.getParty();
if (party == null) {
mcMMOPlayer.togglePartyChat();
player.sendMessage(LocaleLoader.getString("Commands.Party.None"));
return;
}
ChatManager.handlePartyChat(plugin, party, player.getName(), player.getDisplayName(), event.getMessage(), isAsync);
ChatManager.handlePartyChat(plugin, party, player.getName(), player.getDisplayName(), event.getMessage(), event.isAsynchronous());
event.setCancelled(true);
}
else if (mcMMOPlayer.getAdminChatMode()) {
ChatManager.handleAdminChat(plugin, player.getName(), player.getDisplayName(), event.getMessage(), isAsync);
ChatManager.handleAdminChat(plugin, player.getName(), player.getDisplayName(), event.getMessage(), event.isAsynchronous());
event.setCancelled(true);
}
}

View File

@@ -10,10 +10,6 @@ import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
public class SelfListener implements Listener {
protected Player player;
protected float skillValue;
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerLevelUp(McMMOPlayerLevelUpEvent event) {
if (!Config.getInstance().getLevelUpEffectsEnabled()) {
@@ -26,8 +22,8 @@ public class SelfListener implements Listener {
return;
}
player = event.getPlayer();
skillValue = event.getSkillLevel();
Player player = event.getPlayer();
float skillValue = event.getSkillLevel();
if ((skillValue % tier) == 0) {
ParticleEffectUtils.runescapeModeCelebration(player, event.getSkill());

View File

@@ -11,13 +11,13 @@ import org.getspout.spoutapi.gui.Button;
import org.getspout.spoutapi.gui.ScreenType;
import org.getspout.spoutapi.player.SpoutPlayer;
import com.gmail.nossr50.config.spout.SpoutConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.spout.buttons.McMMOButton;
import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
import com.gmail.nossr50.datatypes.spout.popups.McMMOMenu;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.spout.SpoutUtils;
public class SpoutListener implements Listener {
@@ -32,8 +32,8 @@ public class SpoutListener implements Listener {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(spoutPlayer);
// TODO: Add custom titles based on skills
if (SpoutUtils.showPowerLevel) {
spoutPlayer.setTitle(LocaleLoader.getString("Spout.Title", spoutPlayer.getName(), mcMMOPlayer.getPowerLevel()));
if (SpoutConfig.getInstance().getShowPowerLevel()) {
spoutPlayer.setTitle(LocaleLoader.getString("Spout.Title", spoutPlayer.getTitle(), mcMMOPlayer.getPowerLevel()));
}
mcMMOPlayer.getProfile().setSpoutHud(new McMMOHud(mcMMOPlayer)); // Setup Party HUD stuff
@@ -81,7 +81,7 @@ public class SpoutListener implements Listener {
return;
}
if (event.getKey() == SpoutUtils.menuKey) {
if (event.getKey() == SpoutConfig.getInstance().getMenuKey()) {
McMMOHud spoutHud = UserManager.getPlayer(spoutPlayer).getProfile().getSpoutHud();
if (!spoutHud.isMenuOpened()) {

View File

@@ -21,6 +21,12 @@ import com.gmail.nossr50.util.blockmeta.conversion.BlockStoreConversionMain;
public class WorldListener implements Listener {
private ArrayList<BlockStoreConversionMain> converters = new ArrayList<BlockStoreConversionMain>();
private final mcMMO plugin;
public WorldListener(final mcMMO plugin) {
this.plugin = plugin;
}
/**
* Monitor StructureGrow events.
*
@@ -30,9 +36,9 @@ public class WorldListener implements Listener {
public void onStructureGrow(StructureGrowEvent event) {
Location location = event.getLocation();
if (mcMMO.placeStore.isTrue(location.getBlockX(), location.getBlockY(), location.getBlockZ(), location.getWorld())) {
if (mcMMO.getPlaceStore().isTrue(location.getBlockX(), location.getBlockY(), location.getBlockZ(), location.getWorld())) {
for (BlockState blockState : event.getBlocks()) {
mcMMO.placeStore.setFalse(blockState);
mcMMO.getPlaceStore().setFalse(blockState);
}
}
}
@@ -47,11 +53,11 @@ public class WorldListener implements Listener {
World world = event.getWorld();
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
if (!dataDir.exists() || mcMMO.p == null) {
if (!dataDir.exists() || plugin == null) {
return;
}
mcMMO.p.getLogger().info("Converting block storage for " + world.getName() + " to a new format.");
plugin.getLogger().info("Converting block storage for " + world.getName() + " to a new format.");
BlockStoreConversionMain converter = new BlockStoreConversionMain(world);
converter.run();
@@ -65,7 +71,7 @@ public class WorldListener implements Listener {
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onWorldUnload(WorldUnloadEvent event) {
mcMMO.placeStore.unloadWorld(event.getWorld());
mcMMO.getPlaceStore().unloadWorld(event.getWorld());
}
/**
@@ -77,6 +83,6 @@ public class WorldListener implements Listener {
public void onChunkUnload(ChunkUnloadEvent event) {
Chunk chunk = event.getChunk();
mcMMO.placeStore.chunkUnloaded(chunk.getX(), chunk.getZ(), event.getWorld());
mcMMO.getPlaceStore().chunkUnloaded(chunk.getX(), chunk.getZ(), event.getWorld());
}
}

View File

@@ -23,14 +23,12 @@ import com.gmail.nossr50.config.mods.CustomToolConfig;
import com.gmail.nossr50.config.spout.SpoutConfig;
import com.gmail.nossr50.config.treasure.TreasureConfig;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.LeaderboardManager;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.listeners.BlockListener;
import com.gmail.nossr50.listeners.EntityListener;
import com.gmail.nossr50.listeners.InventoryListener;
import com.gmail.nossr50.listeners.PlayerListener;
import com.gmail.nossr50.listeners.SelfListener;
import com.gmail.nossr50.listeners.SpoutListener;
import com.gmail.nossr50.listeners.WorldListener;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.metrics.MetricsManager;
@@ -39,7 +37,6 @@ import com.gmail.nossr50.runnables.SaveTimerTask;
import com.gmail.nossr50.runnables.database.UserPurgeTask;
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.runnables.skills.SkillMonitorTask;
import com.gmail.nossr50.skills.child.ChildConfig;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.skills.repair.RepairableManager;
@@ -56,43 +53,43 @@ import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.spout.SpoutUtils;
public class mcMMO extends JavaPlugin {
private final PlayerListener playerListener = new PlayerListener(this);
private final BlockListener blockListener = new BlockListener(this);
private final EntityListener entityListener = new EntityListener(this);
private final InventoryListener inventoryListener = new InventoryListener(this);
private final SelfListener selfListener = new SelfListener();
private final WorldListener worldListener = new WorldListener();
/* Managers */
private static ChunkManager placeStore;
private static RepairableManager repairableManager;
private static DatabaseManager databaseManager;
public static mcMMO p;
public static ChunkManager placeStore;
public static RepairableManager repairableManager;
// Jar Stuff
public static File mcmmo;
// File Paths
/* File Paths */
private static String mainDirectory;
private static String flatFileDirectory;
private static String usersFile;
private static String modDirectory;
// Update Check
public boolean updateAvailable;
public static mcMMO p;
// Spout Check
public static boolean spoutEnabled = false;
// Jar Stuff
public static File mcmmo;
// Update Check
private boolean updateAvailable;
/* Plugin Checks */
private static boolean spoutEnabled;
private static boolean combatTagEnabled;
// XP Event Check
private boolean xpEventEnabled = false;
private boolean xpEventEnabled;
// Metadata Values
/* Metadata Values */
public final static String entityMetadataKey = "mcMMO: Spawned Entity";
public final static String blockMetadataKey = "mcMMO: Piston Tracking";
public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace";
public final static String tntMetadataKey = "mcMMO: Tracked TNT";
public final static String customNameKey = "mcMMO: Custom Name";
public final static String customVisibleKey = "mcMMO: Name Visibility";
public final static String droppedItemKey = "mcMMO: Tracked Item";
public final static String infiniteArrowKey = "mcMMO: Infinite Arrow";
public final static String bowForceKey = "mcMMO: Bow Force";
public final static String arrowDistanceKey = "mcMMO: Arrow Distance";
public static FixedMetadataValue metadataValue;
@@ -110,33 +107,23 @@ public class mcMMO extends JavaPlugin {
setupSpout();
loadConfigFiles();
if (!Config.getInstance().getUseMySQL()) {
UserManager.loadUsers();
}
combatTagEnabled = getServer().getPluginManager().getPlugin("CombatTag") != null;
databaseManager = new DatabaseManager(this, Config.getInstance().getUseMySQL());
registerEvents();
registerCustomRecipes();
PartyManager.loadParties();
// Setup the leader boards
if (Config.getInstance().getUseMySQL()) {
// TODO: Why do we have to check for a connection that hasn't be made yet?
DatabaseManager.checkConnected();
DatabaseManager.createStructure();
}
else {
LeaderboardManager.updateLeaderboards();
}
for (Player player : getServer().getOnlinePlayers()) {
UserManager.addUser(player); // In case of reload add all users back into UserManager
}
getLogger().info("Version " + getDescription().getVersion() + " is enabled!");
debug("Version " + getDescription().getVersion() + " is enabled!");
scheduleTasks();
registerCommands();
CommandRegistrationManager.registerCommands();
MetricsManager.setup();
@@ -168,7 +155,6 @@ public class mcMMO extends JavaPlugin {
@Override
public void onDisable() {
try {
reloadDisableHelper(); // Prevent Berserk from getting "stuck"
UserManager.saveAll(); // Make sure to save player information if the server shuts down
PartyManager.saveParties(); // Save our parties
placeStore.saveAll(); // Save our metadata
@@ -198,7 +184,7 @@ public class mcMMO extends JavaPlugin {
}
}
getLogger().info("Was disabled."); // How informative!
debug("Was disabled."); // How informative!
}
public static String getMainDirectory() {
@@ -217,6 +203,10 @@ public class mcMMO extends JavaPlugin {
return modDirectory;
}
public boolean isUpdateAvailable() {
return updateAvailable;
}
public boolean isXPEventEnabled() {
return xpEventEnabled;
}
@@ -233,6 +223,26 @@ public class mcMMO extends JavaPlugin {
getLogger().info("[Debug] " + message);
}
public static ChunkManager getPlaceStore() {
return placeStore;
}
public static DatabaseManager getDatabaseManager() {
return databaseManager;
}
public static RepairableManager getRepairableManager() {
return repairableManager;
}
public static boolean isSpoutEnabled() {
return spoutEnabled;
}
public static boolean isCombatTagEnabled() {
return combatTagEnabled;
}
/**
* Setup the various storage file paths
*/
@@ -304,8 +314,7 @@ public class mcMMO extends JavaPlugin {
spoutEnabled = true;
SpoutConfig.getInstance();
SpoutUtils.setupSpoutConfigs();
SpoutUtils.registerCustomEvent();
getServer().getPluginManager().registerEvents(new SpoutListener(), this);
SpoutUtils.preCacheFiles();
SpoutUtils.reloadSpoutPlayers(); // Handle spout players after a /reload
}
@@ -315,53 +324,12 @@ public class mcMMO extends JavaPlugin {
PluginManager pluginManager = getServer().getPluginManager();
// Register events
pluginManager.registerEvents(playerListener, this);
pluginManager.registerEvents(blockListener, this);
pluginManager.registerEvents(entityListener, this);
pluginManager.registerEvents(inventoryListener, this);
pluginManager.registerEvents(selfListener, this);
pluginManager.registerEvents(worldListener, this);
}
/**
* Register the commands.
*/
private void registerCommands() {
CommandRegistrationManager.registerSkillCommands();
// mc* commands
CommandRegistrationManager.registerMcpurgeCommand();
CommandRegistrationManager.registerMcremoveCommand();
CommandRegistrationManager.registerMcabilityCommand();
CommandRegistrationManager.registerMcgodCommand();
CommandRegistrationManager.registerMcmmoCommand();
CommandRegistrationManager.registerMcrefreshCommand();
CommandRegistrationManager.registerMctopCommand();
CommandRegistrationManager.registerMcrankCommand();
CommandRegistrationManager.registerMcstatsCommand();
// Party commands
CommandRegistrationManager.registerAdminChatCommand();
CommandRegistrationManager.registerPartyCommand();
CommandRegistrationManager.registerPartyChatCommand();
CommandRegistrationManager.registerPtpCommand();
// Other commands
CommandRegistrationManager.registerAddxpCommand();
CommandRegistrationManager.registerAddlevelsCommand();
CommandRegistrationManager.registerMmoeditCommand();
CommandRegistrationManager.registerInspectCommand();
CommandRegistrationManager.registerXprateCommand();
CommandRegistrationManager.registerMmoupdateCommand();
CommandRegistrationManager.registerSkillresetCommand();
CommandRegistrationManager.registerHardcoreCommand();
CommandRegistrationManager.registerVampirismCommand();
CommandRegistrationManager.registerMcnotifyCommand();
CommandRegistrationManager.registerMobhealthCommand();
// Spout commands
CommandRegistrationManager.registerXplockCommand();
CommandRegistrationManager.registerMchudCommand();
pluginManager.registerEvents(new PlayerListener(this), this);
pluginManager.registerEvents(new BlockListener(this), this);
pluginManager.registerEvents(new EntityListener(this), this);
pluginManager.registerEvents(new InventoryListener(this), this);
pluginManager.registerEvents(new SelfListener(), this);
pluginManager.registerEvents(new WorldListener(this), this);
}
private void registerCustomRecipes() {
@@ -373,52 +341,29 @@ public class mcMMO extends JavaPlugin {
private void scheduleTasks() {
// Periodic save timer (Saves every 10 minutes by default)
long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
// Regen & Cooldown timer (Runs every second)
new SkillMonitorTask().runTaskTimer(this, 20, 20);
// Bleed timer (Runs every two seconds)
new BleedTimerTask().runTaskTimer(this, 40, 40);
// Old & Powerless User remover
int purgeInterval = Config.getInstance().getPurgeInterval();
UserPurgeTask userPurgeTask = new UserPurgeTask();
long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60 * 60 * 20;
if (purgeInterval == 0) {
userPurgeTask.runTaskLater(this, 40);
if (purgeIntervalTicks == 0) {
new UserPurgeTask().runTaskLater(this, 40); // Start 2 seconds after startup.
}
else if (purgeInterval > 0) {
long purgeIntervalTicks = purgeInterval * 60 * 60 * 20;
userPurgeTask.runTaskTimer(this, purgeIntervalTicks, purgeIntervalTicks);
else if (purgeIntervalTicks > 0) {
new UserPurgeTask().runTaskTimer(this, purgeIntervalTicks, purgeIntervalTicks);
}
// Automatically remove old members from parties
long kickInterval = Config.getInstance().getAutoPartyKickInterval();
PartyAutoKickTask partyAutoKickTask = new PartyAutoKickTask();
long kickIntervalTicks = Config.getInstance().getAutoPartyKickInterval() * 60 * 60 * 20;
if (kickInterval == 0) {
partyAutoKickTask.runTaskLater(this, 40); // Start 2 seconds after startup.
if (kickIntervalTicks == 0) {
new PartyAutoKickTask().runTaskLater(this, 40); // Start 2 seconds after startup.
}
else if (kickInterval > 0) {
long kickIntervalTicks = kickInterval * 60 * 60 * 20;
partyAutoKickTask.runTaskTimer(this, kickIntervalTicks, kickIntervalTicks);
}
}
/**
* Because /reload is the biggest piece of garbage in existence,
* we have to do some special checks to keep it from breaking everything.
*/
private void reloadDisableHelper() {
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers().values()) {
if (mcMMOPlayer.getAbilityMode(AbilityType.BERSERK)) {
mcMMOPlayer.setAbilityMode(AbilityType.BERSERK, false);
mcMMOPlayer.getPlayer().setCanPickupItems(true);
}
else if (kickIntervalTicks > 0) {
new PartyAutoKickTask().runTaskTimer(this, kickIntervalTicks, kickIntervalTicks);
}
}
}

View File

@@ -2,10 +2,10 @@ package com.gmail.nossr50.party;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@@ -15,13 +15,13 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.party.PartyLoaderTask;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.UserManager;
public final class PartyManager {
private static String partiesFilePath = mcMMO.p.getDataFolder().getPath() + File.separator + "FlatFileStuff" + File.separator + "parties.yml";
private static String partiesFilePath = mcMMO.getFlatFileDirectory() + "parties.yml";
private static List<Party> parties = new ArrayList<Party>();
private static File partyFile = new File(partiesFilePath);
private PartyManager() {}
@@ -99,7 +99,7 @@ public final class PartyManager {
* @param player The player to check
* @return all the players in the player's party
*/
public static List<OfflinePlayer> getAllMembers(Player player) {
public static LinkedHashSet<String> getAllMembers(Player player) {
Party party = UserManager.getPlayer(player).getParty();
if (party == null) {
@@ -165,8 +165,8 @@ public final class PartyManager {
*/
public static Party getPlayerParty(String playerName) {
for (Party party : parties) {
for (OfflinePlayer member : party.getMembers()) {
if (member.getName().equalsIgnoreCase(playerName)) {
for (String memberName : party.getMembers()) {
if (memberName.equalsIgnoreCase(playerName)) {
return party;
}
}
@@ -191,9 +191,9 @@ public final class PartyManager {
* @param party The party
*/
public static void removeFromParty(OfflinePlayer player, Party party) {
List<OfflinePlayer> members = party.getMembers();
LinkedHashSet<String> members = party.getMembers();
members.remove(player);
members.remove(player.getName());
if (members.isEmpty()) {
parties.remove(party);
@@ -201,7 +201,7 @@ public final class PartyManager {
else {
// If the leaving player was the party leader, appoint a new leader from the party members
if (party.getLeader().equalsIgnoreCase(player.getName())) {
String newLeader = members.get(0).getName();
String newLeader = members.iterator().next();
party.setLeader(newLeader);
}
@@ -212,6 +212,7 @@ public final class PartyManager {
if (mcMMOPlayer != null) {
mcMMOPlayer.removeParty();
mcMMOPlayer.setPartyChat(false);
mcMMOPlayer.setItemShareModifier(10);
}
}
@@ -222,13 +223,14 @@ public final class PartyManager {
* @param party The party to remove
*/
public static void disbandParty(Party party) {
List<OfflinePlayer> members = party.getMembers();
LinkedHashSet<String> members = party.getMembers();
for (OfflinePlayer member : members) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(member.getName());
for (String memberName : members) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(memberName);
if (mcMMOPlayer != null) {
mcMMOPlayer.removeParty();
mcMMOPlayer.setPartyChat(false);
mcMMOPlayer.setItemShareModifier(10);
}
}
@@ -361,7 +363,8 @@ public final class PartyManager {
informPartyMembersJoin(player, party);
mcMMOPlayer.setParty(party);
party.getMembers().add(player);
party.getMembers().add(player.getName());
}
/**
@@ -439,28 +442,11 @@ public final class PartyManager {
* Load party file.
*/
public static void loadParties() {
try {
mcMMO.p.getServer().getOfflinePlayer("nossr50"); // TODO: Find a less-hacky way to manage reloading.
}
catch (IndexOutOfBoundsException ex){
new PartyLoaderTask().runTaskLater(mcMMO.p, 0);
if (!partyFile.exists()) {
return;
}
File file = new File(partiesFilePath);
if (!file.exists()) {
return;
}
YamlConfiguration partiesFile = new YamlConfiguration();
try {
partiesFile.load(file);
}
catch (Exception e) {
e.printStackTrace();
}
YamlConfiguration partiesFile = YamlConfiguration.loadConfiguration(partyFile);
for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
Party party = new Party();
@@ -469,15 +455,14 @@ public final class PartyManager {
party.setLeader(partiesFile.getString(partyName + ".Leader"));
party.setPassword(partiesFile.getString(partyName + ".Password"));
party.setLocked(partiesFile.getBoolean(partyName + ".Locked"));
party.setXpShareMode(ShareHandler.ShareMode.getFromString(partiesFile.getString(partyName + ".ExpShareMode")));
party.setItemShareMode(ShareHandler.ShareMode.getFromString(partiesFile.getString(partyName + ".ItemShareMode")));
party.setXpShareMode(ShareHandler.ShareMode.getShareMode(partiesFile.getString(partyName + ".ExpShareMode", "NONE")));
party.setItemShareMode(ShareHandler.ShareMode.getShareMode(partiesFile.getString(partyName + ".ItemShareMode", "NONE")));
List<String> memberNames = partiesFile.getStringList(partyName + ".Members");
List<OfflinePlayer> members = party.getMembers();
Server server = mcMMO.p.getServer();
LinkedHashSet<String> members = party.getMembers();
for (String memberName : memberNames) {
members.add(server.getOfflinePlayer(memberName));
members.add(memberName);
}
parties.add(party);
@@ -488,10 +473,8 @@ public final class PartyManager {
* Save party file.
*/
public static void saveParties() {
File file = new File(partiesFilePath);
if (file.exists()) {
file.delete();
if (partyFile.exists()) {
partyFile.delete();
}
YamlConfiguration partiesFile = new YamlConfiguration();
@@ -507,15 +490,17 @@ public final class PartyManager {
List<String> memberNames = new ArrayList<String>();
for (OfflinePlayer member : party.getMembers()) {
memberNames.add(member.getName());
for (String member : party.getMembers()) {
if (!memberNames.contains(member)) {
memberNames.add(member);
}
}
partiesFile.set(partyName + ".Members", memberNames);
}
try {
partiesFile.save(new File(partiesFilePath));
partiesFile.save(partyFile);
}
catch (Exception e) {
e.printStackTrace();

View File

@@ -8,11 +8,12 @@ import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.party.ItemWeightConfig;
import com.gmail.nossr50.datatypes.party.ItemShareType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
public final class ShareHandler {
@@ -21,15 +22,19 @@ public final class ShareHandler {
EQUAL,
RANDOM;
public static ShareMode getFromString(String string) {
public static ShareMode getShareMode(String string) {
try {
return valueOf(string);
}
catch (IllegalArgumentException exception) {
return NONE;
}
catch (NullPointerException exception) {
return NONE;
catch (IllegalArgumentException ex) {
if (string.equalsIgnoreCase("even")) {
return EQUAL;
}
else if (CommandUtils.shouldDisableToggle(string)) {
return NONE;
}
return null;
}
}
};
@@ -47,7 +52,7 @@ public final class ShareHandler {
* @param skillType Skill being used
* @return True is the xp has been shared
*/
public static boolean handleXpShare(int xp, McMMOPlayer mcMMOPlayer, SkillType skillType) {
public static boolean handleXpShare(float xp, McMMOPlayer mcMMOPlayer, SkillType skillType) {
Party party = mcMMOPlayer.getParty();
switch (party.getXpShareMode()) {
@@ -66,18 +71,17 @@ public final class ShareHandler {
shareBonus = Config.getInstance().getPartyShareBonusCap();
}
double splitXp = xp / partySize * shareBonus;
int roundedXp = (int) Math.ceil(splitXp);
float splitXp = (float) (xp / partySize * shareBonus);
for (Player member : nearMembers) {
UserManager.getPlayer(member).beginUnsharedXpGain(skillType, roundedXp);
UserManager.getPlayer(member).beginUnsharedXpGain(skillType, splitXp);
}
mcMMOPlayer.beginUnsharedXpGain(skillType, roundedXp);
mcMMOPlayer.beginUnsharedXpGain(skillType, splitXp);
return true;
case NONE:
// Fallthrough
default:
return false;
}
@@ -99,16 +103,9 @@ public final class ShareHandler {
ItemStack newStack = itemStack.clone();
newStack.setAmount(1);
if (ItemUtils.isMobDrop(itemStack) && !party.sharingLootDrops()) {
return false;
}
else if (ItemUtils.isMiningDrop(itemStack) && !party.sharingMiningDrops()) {
return false;
}
else if (ItemUtils.isHerbalismDrop(itemStack) && !party.sharingHerbalismDrops()) {
return false;
}
else if (ItemUtils.isWoodcuttingDrop(itemStack) && !party.sharingWoodcuttingDrops()) {
ItemShareType dropType = ItemShareType.getShareType(itemStack);
if (dropType == null || !party.sharingDrops(dropType)) {
return false;
}
@@ -160,6 +157,7 @@ public final class ShareHandler {
winningPlayer.updateInventory();
}
return true;
case RANDOM:
nearMembers = PartyManager.getNearMembers(player, party, Config.getInstance().getPartyShareRange());
@@ -188,8 +186,8 @@ public final class ShareHandler {
winningPlayer.updateInventory();
}
return true;
case NONE:
// Fallthrough
default:
return false;
}

View File

@@ -21,11 +21,11 @@ public class StickyPistonTrackerTask extends BukkitRunnable {
Block newBlock = block.getRelative(direction);
Block originalBlock = newBlock.getRelative(direction);
if (originalBlock.getType() != Material.AIR || !mcMMO.placeStore.isTrue(originalBlock)) {
if (originalBlock.getType() != Material.AIR || !mcMMO.getPlaceStore().isTrue(originalBlock)) {
return;
}
mcMMO.placeStore.setFalse(originalBlock);
mcMMO.placeStore.setTrue(newBlock);
mcMMO.getPlaceStore().setFalse(originalBlock);
mcMMO.getPlaceStore().setTrue(newBlock);
}
}

View File

@@ -6,7 +6,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
public class McrankCommandAsyncTask extends BukkitRunnable {
private final String playerName;
@@ -19,7 +21,7 @@ public class McrankCommandAsyncTask extends BukkitRunnable {
@Override
public void run() {
Map<String, Integer> skills = DatabaseManager.readSQLRank(playerName);
Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName);
new McrankCommandDisplayTask(skills, sender, playerName).runTaskLater(mcMMO.p, 1);
}

View File

@@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
@@ -24,27 +25,22 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
@Override
public void run() {
Player player = mcMMO.p.getServer().getPlayer(playerName);
Integer rank;
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
for (SkillType skillType : SkillType.values()) {
if ((sender instanceof Player && !Permissions.skillEnabled(sender, skillType)) || skillType.isChildSkill()) {
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || (player != null && !Permissions.skillEnabled(player, skill))) {
continue;
}
if (skills.get(skillType.name()) == null) {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), LocaleLoader.getString("Commands.mcrank.Unranked")));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), skills.get(skillType.name())));
}
rank = skills.get(skill.name());
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skill), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
}
if (skills.get("ALL") == null) {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", LocaleLoader.getString("Commands.mcrank.Unranked")));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", skills.get("ALL")));
}
rank = skills.get("ALL");
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
}
}

View File

@@ -1,33 +1,31 @@
package com.gmail.nossr50.runnables.commands;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
public class MctopCommandAsyncTask extends BukkitRunnable {
private CommandSender sender;
private String query;
private int page;
public MctopCommandAsyncTask(int page, String query, CommandSender sender) {
this.page = page;
this.query = query;
this.query = query.equalsIgnoreCase("ALL") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : query;
this.sender = sender;
}
@Override
public void run() {
String tablePrefix = Config.getInstance().getMySQLTablePrefix();
final HashMap<Integer, ArrayList<String>> userslist = DatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10");
final Collection<ArrayList<String>> userStats = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10").values();
new MctopCommandDisplayTask(userslist, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1);
new MctopCommandDisplayTask(userStats, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1);
}
}

View File

@@ -1,7 +1,7 @@
package com.gmail.nossr50.runnables.commands;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -11,13 +11,13 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.StringUtils;
public class MctopCommandDisplayTask extends BukkitRunnable {
private HashMap<Integer, ArrayList<String>> userslist;
private Collection<ArrayList<String>> userStats;
private CommandSender sender;
private String query;
private int page;
public MctopCommandDisplayTask(HashMap<Integer, ArrayList<String>> userslist, int page, String query, CommandSender sender) {
this.userslist = userslist;
public MctopCommandDisplayTask(Collection<ArrayList<String>> userStats, int page, String query, CommandSender sender) {
this.userStats = userStats;
this.page = page;
this.query = query;
this.sender = sender;
@@ -33,13 +33,12 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
}
int place = (page * 10) - 9;
for (int i = 1; i <= 10; i++) {
if (userslist.get(i) == null) {
break;
}
for (ArrayList<String> stat : userStats) {
String digit = (place < 10) ? "0" : "" + String.valueOf(place);
// Format: 1. Playername - skill value
sender.sendMessage(place + ". " + ChatColor.GREEN + userslist.get(i).get(1) + " - " + ChatColor.WHITE + userslist.get(i).get(0));
sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.get(1) + " - " + ChatColor.WHITE + stat.get(0));
place++;
}

View File

@@ -7,7 +7,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.StringUtils;
@@ -158,7 +158,7 @@ public class SQLConversionTask extends BukkitRunnable {
}
// Check to see if the user is in the DB
id = DatabaseManager.getInt("SELECT id FROM "
id = SQLDatabaseManager.getInt("SELECT id FROM "
+ tablePrefix
+ "users WHERE user = '" + playerName + "'");
@@ -166,11 +166,11 @@ public class SQLConversionTask extends BukkitRunnable {
theCount++;
// Update the skill values
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "users SET lastlogin = " + 0
+ " WHERE id = " + id);
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "skills SET "
+ " taming = taming+" + StringUtils.getInt(taming)
@@ -186,7 +186,7 @@ public class SQLConversionTask extends BukkitRunnable {
+ ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics)
+ ", fishing = fishing+" + StringUtils.getInt(fishing)
+ " WHERE user_id = " + id);
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "experience SET "
+ " taming = " + StringUtils.getInt(tamingXP)
@@ -207,24 +207,24 @@ public class SQLConversionTask extends BukkitRunnable {
theCount++;
// Create the user in the DB
DatabaseManager.write("INSERT INTO "
SQLDatabaseManager.write("INSERT INTO "
+ tablePrefix
+ "users (user, lastlogin) VALUES ('"
+ playerName + "',"
+ System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR + ")");
id = DatabaseManager.getInt("SELECT id FROM "
id = SQLDatabaseManager.getInt("SELECT id FROM "
+ tablePrefix
+ "users WHERE user = '"
+ playerName + "'");
DatabaseManager.write("INSERT INTO "
SQLDatabaseManager.write("INSERT INTO "
+ tablePrefix
+ "skills (user_id) VALUES (" + id + ")");
DatabaseManager.write("INSERT INTO "
SQLDatabaseManager.write("INSERT INTO "
+ tablePrefix
+ "experience (user_id) VALUES (" + id
+ ")");
// Update the skill values
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "users SET lastlogin = " + 0
+ " WHERE id = " + id);
@@ -234,7 +234,7 @@ public class SQLConversionTask extends BukkitRunnable {
+ "users SET party = '" + party
+ "' WHERE id = " + id);
*/
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "skills SET "
+ " taming = taming+" + StringUtils.getInt(taming)
@@ -250,7 +250,7 @@ public class SQLConversionTask extends BukkitRunnable {
+ ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics)
+ ", fishing = fishing+" + StringUtils.getInt(fishing)
+ " WHERE user_id = " + id);
DatabaseManager.write("UPDATE "
SQLDatabaseManager.write("UPDATE "
+ tablePrefix
+ "experience SET "
+ " taming = " + StringUtils.getInt(tamingXP)

View File

@@ -4,13 +4,13 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.util.player.UserManager;
public class SQLReconnectTask extends BukkitRunnable {
@Override
public void run() {
if (DatabaseManager.checkConnected()) {
if (SQLDatabaseManager.checkConnected()) {
UserManager.saveAll(); // Save all profiles
UserManager.clearAll(); // Clear the profiles

View File

@@ -2,26 +2,16 @@ package com.gmail.nossr50.runnables.database;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.database.LeaderboardManager;
public class UserPurgeTask extends BukkitRunnable {
@Override
public void run() {
if (Config.getInstance().getUseMySQL()) {
DatabaseManager.purgePowerlessSQL();
mcMMO.getDatabaseManager().purgePowerlessUsers();
if (Config.getInstance().getOldUsersCutoff() != -1) {
DatabaseManager.purgeOldSQL();
}
}
else {
LeaderboardManager.purgePowerlessFlatfile();
if (Config.getInstance().getOldUsersCutoff() != -1) {
LeaderboardManager.purgeOldFlatfile();
}
if (Config.getInstance().getOldUsersCutoff() != -1) {
mcMMO.getDatabaseManager().purgeOldUsers();
}
}
}

View File

@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.items;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -29,19 +28,18 @@ public class ChimaeraWingWarmup extends BukkitRunnable {
private void checkChimaeraWingTeleport() {
Player player = mcMMOPlayer.getPlayer();
Location previousLocation = mcMMOPlayer.getTeleportCommenceLocation();
Location newLocation = mcMMOPlayer.getPlayer().getLocation();
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
ItemStack inHand = player.getItemInHand();
mcMMOPlayer.setTeleportCommenceLocation(null);
if (newLocation.distanceSquared(previousLocation) > 1.0 || !player.getInventory().containsAtLeast(ChimaeraWing.getChimaeraWing(0), 1)) {
player.sendMessage(ChatColor.DARK_RED + "Teleportation canceled!"); //TODO Locale!
if (player.getLocation().distanceSquared(previousLocation) > 1.0 || !player.getInventory().containsAtLeast(ChimaeraWing.getChimaeraWing(0), 1)) {
player.sendMessage(LocaleLoader.getString("Teleport.Cancelled"));
return;
}
if (!ItemUtils.isChimaeraWing(inHand) || inHand.getAmount() < Config.getInstance().getChimaeraUseCost()) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore", "Chimaera Wings")); //TODO Locale!
player.sendMessage(LocaleLoader.getString("Skills.NeedMore", LocaleLoader.getString("Item.ChimaeraWing.Name")));
return;
}

View File

@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.items;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@@ -44,7 +43,7 @@ public class TeleportationWarmup extends BukkitRunnable {
}
if (newLocation.distanceSquared(previousLocation) > 1.0) {
teleportingPlayer.sendMessage(ChatColor.DARK_RED + "Teleportation canceled!"); //TODO Locale!
teleportingPlayer.sendMessage(LocaleLoader.getString("Teleport.Cancelled"));
return;
}

View File

@@ -1,12 +1,15 @@
package com.gmail.nossr50.runnables.party;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import org.bukkit.OfflinePlayer;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.party.PartyManager;
@@ -19,6 +22,7 @@ public class PartyAutoKickTask extends BukkitRunnable {
private void updatePartyMembers() {
HashMap<OfflinePlayer, Party> toRemove = new HashMap<OfflinePlayer, Party>();
List<String> processedPlayers = new ArrayList<String>();
long currentTime = System.currentTimeMillis();
long kickTime = 24L * 60L * 60L * 1000L * Config.getInstance().getAutoPartyKickTime();
@@ -26,10 +30,16 @@ public class PartyAutoKickTask extends BukkitRunnable {
for (Iterator<Party> partyIterator = PartyManager.getParties().iterator(); partyIterator.hasNext();) {
Party party = partyIterator.next();
for (OfflinePlayer member : party.getMembers()) {
if (currentTime - member.getLastPlayed() > kickTime) {
for (String memberName : party.getMembers()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberName);
if ((currentTime - member.getLastPlayed() > kickTime) || processedPlayers.contains(memberName)) {
toRemove.put(member, party);
}
if (!processedPlayers.contains(memberName)) {
processedPlayers.add(memberName);
}
}
}

View File

@@ -1,12 +0,0 @@
package com.gmail.nossr50.runnables.party;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.party.PartyManager;
public class PartyLoaderTask extends BukkitRunnable {
@Override
public void run() {
PartyManager.loadParties();
}
}

View File

@@ -1,5 +1,6 @@
package com.gmail.nossr50.runnables.player;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -19,8 +20,10 @@ public class PlayerProfileSaveTask extends BukkitRunnable {
public void run() {
playerProfile.save();
if (!mcMMOPlayer.getPlayer().isOnline()) {
UserManager.remove(playerProfile.getPlayerName());
Player player = mcMMOPlayer.getPlayer();
if (!player.isOnline()) {
UserManager.remove(player.getName());
}
}
}

View File

@@ -0,0 +1,27 @@
package com.gmail.nossr50.runnables.scoreboards;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Scoreboard;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
public class ScoreboardChangeTask extends BukkitRunnable {
private Player player;
private Scoreboard oldScoreboard;
public ScoreboardChangeTask(Player player, Scoreboard oldScoreboard) {
this.player = player;
this.oldScoreboard = oldScoreboard;
}
@Override
public void run() {
if (player.isOnline()) {
player.setScoreboard(oldScoreboard);
ScoreboardManager.enablePowerLevelDisplay(player);
}
ScoreboardManager.clearPendingTask(player.getName());
}
}

View File

@@ -0,0 +1,26 @@
package com.gmail.nossr50.runnables.skills;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.AbilityType;
public class AbilityCooldownTask extends BukkitRunnable {
private McMMOPlayer mcMMOPlayer;
private AbilityType ability;
public AbilityCooldownTask(McMMOPlayer mcMMOPlayer, AbilityType ability) {
this.mcMMOPlayer = mcMMOPlayer;
this.ability = ability;
}
@Override
public void run() {
if (mcMMOPlayer.getAbilityInformed(ability)) {
return;
}
mcMMOPlayer.setAbilityInformed(ability, true);
mcMMOPlayer.getPlayer().sendMessage(ability.getAbilityRefresh());
}
}

View File

@@ -0,0 +1,64 @@
package com.gmail.nossr50.runnables.skills;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.skills.abilities.McMMOPlayerAbilityDeactivateEvent;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
public class AbilityDisableTask extends BukkitRunnable {
private McMMOPlayer mcMMOPlayer;
private AbilityType ability;
public AbilityDisableTask(McMMOPlayer mcMMOPlayer, AbilityType ability) {
this.mcMMOPlayer = mcMMOPlayer;
this.ability = ability;
}
@Override
public void run() {
if (!mcMMOPlayer.getAbilityMode(ability)) {
return;
}
Player player = mcMMOPlayer.getPlayer();
switch (ability) {
case SUPER_BREAKER:
case GIGA_DRILL_BREAKER:
SkillUtils.handleAbilitySpeedDecrease(player);
// Fallthrough
case BERSERK:
if (HiddenConfig.getInstance().resendChunksAfterBlockAbility()) {
Misc.resendChunkRadiusAt(player, 1);
}
// Fallthrough
default:
break;
}
McMMOPlayerAbilityDeactivateEvent event = new McMMOPlayerAbilityDeactivateEvent(player, SkillType.byAbility(ability));
mcMMO.p.getServer().getPluginManager().callEvent(event);
mcMMOPlayer.setAbilityMode(ability, false);
mcMMOPlayer.setAbilityInformed(ability, false);
ParticleEffectUtils.playAbilityDisabledEffect(player);
if (mcMMOPlayer.useChatNotifications()) {
player.sendMessage(ability.getAbilityOff());
}
SkillUtils.sendSkillMessage(player, ability.getAbilityPlayerOff(player));
new AbilityCooldownTask(mcMMOPlayer, ability).runTaskLaterAsynchronously(mcMMO.p, ability.getCooldown() * 20);
}
}

View File

@@ -0,0 +1,94 @@
package com.gmail.nossr50.runnables.skills;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.util.Misc;
public class KrakenAttackTask extends BukkitRunnable {
private Creature kraken;
private Player player;
private Location location;
private final boolean GLOBAL_SOUNDS = AdvancedConfig.getInstance().getKrakenGlobalSoundsEnabled();
public KrakenAttackTask(Creature kraken, Player player) {
this.kraken = kraken;
this.player = player;
}
public KrakenAttackTask(Creature kraken, Player player, Location location) {
this.kraken = kraken;
this.player = player;
this.location = location;
}
@Override
public void run() {
if (location != null) {
Location playerLocation = player.getLocation();
if (player.isValid() && playerLocation.getBlock().isLiquid()) {
World world = player.getWorld();
player.damage(AdvancedConfig.getInstance().getKrakenAttackDamage(), kraken);
if (GLOBAL_SOUNDS) {
world.playSound(playerLocation, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
else {
player.playSound(playerLocation, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
world.strikeLightningEffect(playerLocation);
}
else {
player.sendMessage(AdvancedConfig.getInstance().getPlayerEscapeMessage());
player.resetPlayerWeather();
cancel();
}
return;
}
if (!kraken.isValid()) {
player.sendMessage(AdvancedConfig.getInstance().getPlayerDefeatMessage());
player.resetPlayerWeather();
cancel();
}
if (player.isValid()) {
Location location = player.getLocation();
if (!location.getBlock().isLiquid() && AdvancedConfig.getInstance().getKrakenEscapeAllowed()) {
player.sendMessage(AdvancedConfig.getInstance().getPlayerEscapeMessage());
kraken.remove();
player.resetPlayerWeather();
cancel();
return;
}
World world = player.getWorld();
kraken.teleport(player);
player.damage(AdvancedConfig.getInstance().getKrakenAttackDamage(), kraken);
if (GLOBAL_SOUNDS) {
world.playSound(location, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
else {
player.playSound(location, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
world.strikeLightningEffect(location);
}
else {
kraken.remove();
cancel();
}
}
}

View File

@@ -1,36 +0,0 @@
package com.gmail.nossr50.runnables.skills;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
public class SkillMonitorTask extends BukkitRunnable {
@Override
public void run() {
long curTime = System.currentTimeMillis();
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers().values()) {
/*
* MONITOR SKILLS
*/
for (SkillType skill : SkillType.values()) {
if (skill.getTool() != null && skill.getAbility() != null) {
SkillUtils.monitorSkill(mcMMOPlayer, curTime, skill);
}
}
/*
* COOLDOWN MONITORING
*/
for (AbilityType ability : AbilityType.values()) {
if (ability.getCooldown() > 0) {
SkillUtils.watchCooldown(mcMMOPlayer, ability);
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
package com.gmail.nossr50.runnables.skills;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.ToolType;
public class ToolLowerTask extends BukkitRunnable {
private McMMOPlayer mcMMOPlayer;
private ToolType tool;
public ToolLowerTask(McMMOPlayer mcMMOPlayer, ToolType tool) {
this.mcMMOPlayer = mcMMOPlayer;
this.tool = tool;
}
@Override
public void run() {
if (!mcMMOPlayer.getToolPreparationMode(tool)) {
return;
}
mcMMOPlayer.setToolPreparationMode(tool, false);
if (Config.getInstance().getAbilityMessagesEnabled()) {
mcMMOPlayer.getPlayer().sendMessage(tool.getLowerTool());
}
}
}

View File

@@ -38,7 +38,7 @@ public abstract class SkillManager {
return activationChance;
}
public void applyXpGain(int xp) {
public void applyXpGain(float xp) {
mcMMOPlayer.beginXpGain(skill, xp);
}
}

View File

@@ -4,10 +4,12 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.util.Misc;
@@ -65,4 +67,14 @@ public class Archery {
}
}
}
public static Location stringToLocation(String location) {
String[] values = location.split(",");
return new Location(mcMMO.p.getServer().getWorld(values[0]), Double.parseDouble(values[1]), Double.parseDouble(values[2]), Double.parseDouble(values[3]), Float.parseFloat(values[4]), Float.parseFloat(values[5]));
}
public static String locationToString(Location location) {
return location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ() + "," + location.getYaw() + "," + location.getPitch();
}
}

View File

@@ -1,12 +1,13 @@
package com.gmail.nossr50.skills.archery;
import org.bukkit.Location;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -30,9 +31,7 @@ public class ArcheryManager extends SkillManager {
}
public boolean canTrackArrows() {
Player player = getPlayer();
return !(player.getItemInHand().containsEnchantment(Enchantment.ARROW_INFINITE)) && Permissions.arrowRetrieval(player);
return Permissions.arrowRetrieval(getPlayer());
}
/**
@@ -40,20 +39,15 @@ public class ArcheryManager extends SkillManager {
*
* @param target The {@link LivingEntity} damaged by the arrow
*/
public void distanceXpBonus(LivingEntity target) {
Player player = getPlayer();
Location shooterLocation = player.getLocation();
public void distanceXpBonus(LivingEntity target, Entity damager) {
Location firedLocation = Archery.stringToLocation(damager.getMetadata(mcMMO.arrowDistanceKey).get(0).asString());
Location targetLocation = target.getLocation();
if (shooterLocation.getWorld() != targetLocation.getWorld()) {
if (firedLocation.getWorld() != targetLocation.getWorld()) {
return;
}
// Cap distance at 100^2 to prevent teleport exploit.
// TODO: Better way to handle this would be great...
double squaredDistance = Math.min(shooterLocation.distanceSquared(targetLocation), 10000);
applyXpGain((int) (squaredDistance * Archery.DISTANCE_XP_MULTIPLIER));
applyXpGain((int) (firedLocation.distanceSquared(targetLocation) * Archery.DISTANCE_XP_MULTIPLIER));
}
/**

View File

@@ -1,7 +1,10 @@
package com.gmail.nossr50.skills.fishing;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
@@ -49,6 +52,8 @@ public final class Fishing {
abstract protected int getVanillaXPBoostModifier();
}
protected static final HashMap<Material, List<Enchantment>> ENCHANTABLE_CACHE = new HashMap<Material, List<Enchantment>>();
public static int fishermansDietRankLevel1 = AdvancedConfig.getInstance().getFishermanDietRankChange();
public static int fishermansDietRankLevel2 = fishermansDietRankLevel1 * 2;
public static int fishermansDietMaxLevel = fishermansDietRankLevel1 * 5;

View File

@@ -4,9 +4,19 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.WeatherType;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
@@ -14,8 +24,11 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.treasure.TreasureConfig;
@@ -23,7 +36,9 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.datatypes.treasure.FishingTreasure;
import com.gmail.nossr50.datatypes.treasure.ShakeTreasure;
import com.gmail.nossr50.events.fake.FakePlayerFishEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.skills.KrakenAttackTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.fishing.Fishing.Tier;
import com.gmail.nossr50.util.ItemUtils;
@@ -33,6 +48,11 @@ import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
public class FishingManager extends SkillManager {
private final long FISHING_COOLDOWN_SECONDS = 1000L;
private int fishingTries = 0;
private long fishingTimestamp = 0L;
public FishingManager(McMMOPlayer mcMMOPlayer) {
super(mcMMOPlayer, SkillType.FISHING);
}
@@ -45,6 +65,111 @@ public class FishingManager extends SkillManager {
return Permissions.masterAngler(getPlayer());
}
public boolean unleashTheKraken() {
return unleashTheKraken(true);
}
private boolean unleashTheKraken(boolean forceSpawn) {
if (!forceSpawn && (fishingTries < AdvancedConfig.getInstance().getKrakenTriesBeforeRelease() || fishingTries <= Misc.getRandom().nextInt(200))) {
return false;
}
Player player = getPlayer();
World world = player.getWorld();
player.setPlayerWeather(WeatherType.DOWNFALL);
Entity vehicle = player.getVehicle();
if (vehicle != null && vehicle.getType() == EntityType.BOAT) {
vehicle.eject();
vehicle.remove();
}
player.teleport(player.getTargetBlock(null, 100).getLocation(), TeleportCause.PLUGIN);
Location location = player.getLocation();
world.strikeLightningEffect(location);
world.strikeLightningEffect(location);
world.strikeLightningEffect(location);
player.sendMessage(AdvancedConfig.getInstance().getPlayerUnleashMessage());
if (AdvancedConfig.getInstance().getKrakenGlobalSoundsEnabled()) {
world.playSound(location, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
else {
player.playSound(location, Sound.GHAST_SCREAM, Misc.GHAST_VOLUME, Misc.getGhastPitch());
}
String globalMessage = AdvancedConfig.getInstance().getServerUnleashMessage();
if (!globalMessage.isEmpty()) {
mcMMO.p.getServer().broadcastMessage(ChatColor.RED + AdvancedConfig.getInstance().getServerUnleashMessage().replace("(PLAYER)", player.getDisplayName()));
}
player.setItemInHand(null);
Creature kraken = (Creature) world.spawnEntity(player.getEyeLocation(), (Misc.getRandom().nextInt(100) == 0 ? EntityType.CHICKEN : EntityType.SQUID));
kraken.setCustomName(AdvancedConfig.getInstance().getKrakenName());
if (!kraken.isValid()) {
int attackInterval = AdvancedConfig.getInstance().getKrakenAttackInterval() * 20;
new KrakenAttackTask(kraken, player, player.getLocation()).runTaskTimer(mcMMO.p, attackInterval, attackInterval);
if (!forceSpawn) {
fishingTries = 0;
}
return true;
}
kraken.setMaxHealth(AdvancedConfig.getInstance().getKrakenHealth());
kraken.setHealth(kraken.getMaxHealth());
int attackInterval = AdvancedConfig.getInstance().getKrakenAttackInterval() * 20;
new KrakenAttackTask(kraken, player).runTaskTimer(mcMMO.p, attackInterval, attackInterval);
if (!forceSpawn) {
fishingTries = 0;
}
return true;
}
public boolean exploitPrevention() {
if (!AdvancedConfig.getInstance().getKrakenEnabled()) {
return false;
}
long currentTime = System.currentTimeMillis();
boolean hasFished = currentTime < fishingTimestamp + FISHING_COOLDOWN_SECONDS;
fishingTries = hasFished ? fishingTries + 1 : Math.max(fishingTries - 1, 0);
fishingTimestamp = currentTime;
return unleashTheKraken(false);
}
public boolean canIceFish(Block block) {
if (getSkillLevel() < AdvancedConfig.getInstance().getIceFishingUnlockLevel()) {
return false;
}
if (block.getType() != Material.ICE) {
return false;
}
// Make sure this is a body of water, not just a block of ice.
Biome biome = block.getBiome();
boolean isFrozenBiome = (biome == Biome.FROZEN_OCEAN || biome == Biome.FROZEN_RIVER);
if (!isFrozenBiome && block.getRelative(BlockFace.DOWN, 3).getType() == (Material.STATIONARY_WATER)) {
return false;
}
return Permissions.iceFishing(getPlayer());
}
/**
* Gets the loot tier
*
@@ -90,8 +215,38 @@ public class FishingManager extends SkillManager {
return SkillUtils.handleFoodSkills(getPlayer(), skill, eventFoodLevel, Fishing.fishermansDietRankLevel1, Fishing.fishermansDietMaxLevel, rankChange);
}
public void iceFishing(Fish hook, Block block) {
// Make a hole
block.setType(Material.STATIONARY_WATER);
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
Block relative = block.getRelative(x, 0, z);
if (relative.getType() == Material.ICE) {
relative.setType(Material.STATIONARY_WATER);
}
}
}
// Recast in the new spot
mcMMO.p.getServer().getPluginManager().callEvent(new FakePlayerFishEvent(getPlayer(), null, hook, PlayerFishEvent.State.FISHING));
}
public void masterAngler(Fish hook) {
hook.setBiteChance(Math.min(hook.getBiteChance() * Math.max((getSkillLevel() / 10.0), 1.0), 1.0));
Player player = getPlayer();
Biome biome = player.getLocation().getBlock().getBiome();
double biteChance = Math.min(hook.getBiteChance() * Math.max((getSkillLevel() / 200.0), 1.0), 1.0);
if (biome == Biome.RIVER || biome == Biome.OCEAN) {
biteChance = biteChance * 2.0;
}
if (player.isInsideVehicle() && player.getVehicle().getType() == EntityType.BOAT) {
biteChance = biteChance * 2.0;
}
hook.setBiteChance(biteChance);
}
/**
@@ -112,7 +267,7 @@ public class FishingManager extends SkillManager {
player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
treasureXp = treasure.getXp();
ItemStack treasureDrop = treasure.getDrop();
ItemStack treasureDrop = treasure.getDrop().clone(); // Not cloning is bad, m'kay?
if (Permissions.magicHunter(player) && ItemUtils.isEnchantable(treasureDrop) && handleMagicHunter(treasureDrop)) {
player.sendMessage(LocaleLoader.getString("Fishing.MagicFound"));
@@ -142,6 +297,8 @@ public class FishingManager extends SkillManager {
* @param mob The {@link LivingEntity} affected by the ability
*/
public void shakeCheck(LivingEntity target) {
fishingTries--; // Because autoclicking to shake is OK.
if (getShakeProbability() > Misc.getRandom().nextInt(getActivationChance())) {
List<ShakeTreasure> possibleDrops = Fishing.findPossibleDrops(target);
@@ -254,13 +411,7 @@ public class FishingManager extends SkillManager {
return false;
}
List<Enchantment> possibleEnchantments = new ArrayList<Enchantment>();
for (Enchantment enchantment : Enchantment.values()) {
if (enchantment.canEnchantItem(treasureDrop)) {
possibleEnchantments.add(enchantment);
}
}
List<Enchantment> possibleEnchantments = getPossibleEnchantments(treasureDrop);
// This make sure that the order isn't always the same, for example previously Unbreaking had a lot more chance to be used than any other enchant
Collections.shuffle(possibleEnchantments, Misc.getRandom());
@@ -269,17 +420,38 @@ public class FishingManager extends SkillManager {
int specificChance = 1;
for (Enchantment possibleEnchantment : possibleEnchantments) {
if (!treasureDrop.getItemMeta().hasConflictingEnchant(possibleEnchantment) && Misc.getRandom().nextInt(specificChance) == 0) {
treasureDrop.addEnchantment(possibleEnchantment, Misc.getRandom().nextInt(possibleEnchantment.getMaxLevel()) + 1);
specificChance++;
enchanted = true;
if (treasureDrop.getItemMeta().hasConflictingEnchant(possibleEnchantment) || Misc.getRandom().nextInt(specificChance) != 0) {
continue;
}
treasureDrop.addEnchantment(possibleEnchantment, Math.max(Misc.getRandom().nextInt(possibleEnchantment.getMaxLevel()) + 1, possibleEnchantment.getStartLevel()));
specificChance++;
enchanted = true;
}
return enchanted;
}
private List<Enchantment> getPossibleEnchantments(ItemStack treasureDrop) {
Material dropType = treasureDrop.getType();
if (Fishing.ENCHANTABLE_CACHE.containsKey(dropType)) {
return Fishing.ENCHANTABLE_CACHE.get(dropType);
}
List<Enchantment> possibleEnchantments = new ArrayList<Enchantment>();
for (Enchantment enchantment : Enchantment.values()) {
if (enchantment.canEnchantItem(treasureDrop)) {
possibleEnchantments.add(enchantment);
}
}
Fishing.ENCHANTABLE_CACHE.put(dropType, possibleEnchantments);
return possibleEnchantments;
}
/**
* Gets the vanilla XP multiplier
*

View File

@@ -63,7 +63,7 @@ public class Herbalism {
protected static int calculateCatciAndSugarDrops(BlockState blockState) {
Block block = blockState.getBlock();
Material blockType = blockState.getType();
int dropAmount = mcMMO.placeStore.isTrue(block) ? 0 : 1;
int dropAmount = mcMMO.getPlaceStore().isTrue(block) ? 0 : 1;
// Handle the two blocks above it - cacti & sugar cane can only grow 3 high naturally
for (int y = 1; y < 3; y++) {
@@ -73,8 +73,8 @@ public class Herbalism {
break;
}
if (mcMMO.placeStore.isTrue(relativeBlock)) {
mcMMO.placeStore.setFalse(relativeBlock);
if (mcMMO.getPlaceStore().isTrue(relativeBlock)) {
mcMMO.getPlaceStore().setFalse(relativeBlock);
}
else {
dropAmount++;

View File

@@ -118,7 +118,7 @@ public class HerbalismManager extends SkillManager {
Material material = blockState.getType();
boolean oneBlockPlant = !(material == Material.CACTUS || material == Material.SUGAR_CANE_BLOCK);
if (oneBlockPlant && mcMMO.placeStore.isTrue(blockState)) {
if (oneBlockPlant && mcMMO.getPlaceStore().isTrue(blockState)) {
return;
}
@@ -206,8 +206,8 @@ public class HerbalismManager extends SkillManager {
case RED_ROSE:
case YELLOW_FLOWER:
if (mcMMO.placeStore.isTrue(blockState)) {
mcMMO.placeStore.setFalse(blockState);
if (mcMMO.getPlaceStore().isTrue(blockState)) {
mcMMO.getPlaceStore().setFalse(blockState);
return false;
}

View File

@@ -19,6 +19,7 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.mining.BlastMining.Tier;
import com.gmail.nossr50.util.BlockUtils;
@@ -108,6 +109,7 @@ public class MiningManager extends SkillManager{
getProfile().setSkillDATS(AbilityType.BLAST_MINING, System.currentTimeMillis());
mcMMOPlayer.setAbilityInformed(AbilityType.BLAST_MINING, false);
new AbilityCooldownTask(mcMMOPlayer, AbilityType.BLAST_MINING).runTaskLaterAsynchronously(mcMMO.p, AbilityType.BLAST_MINING.getCooldown());
}
/**
@@ -139,13 +141,13 @@ public class MiningManager extends SkillManager{
for (BlockState blockState : ores) {
if (Misc.getRandom().nextFloat() < (yield + oreBonus)) {
if (!mcMMO.placeStore.isTrue(blockState)) {
if (!mcMMO.getPlaceStore().isTrue(blockState)) {
xp += Mining.getBlockXp(blockState);
}
Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack(1)); // Initial block that would have been dropped
if (!mcMMO.placeStore.isTrue(blockState)) {
if (!mcMMO.getPlaceStore().isTrue(blockState)) {
for (int i = 1; i < dropMultiplier; i++) {
Mining.handleSilkTouchDrops(blockState); // Bonus drops - should drop the block & not the items
}
@@ -156,7 +158,7 @@ public class MiningManager extends SkillManager{
if (debrisYield > 0) {
for (BlockState blockState : debris) {
if (Misc.getRandom().nextFloat() < debrisYield) {
Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack(1));
Misc.dropItems(blockState.getLocation(), blockState.getBlock().getDrops());
}
}
}

View File

@@ -40,6 +40,30 @@ public class Repair {
return false;
}
public static String getAnvilMessage(int blockId) {
if (blockId == repairAnvilId) {
return LocaleLoader.getString("Repair.Listener.Anvil");
}
if (blockId == salvageAnvilId) {
return LocaleLoader.getString("Repair.Listener.Anvil2");
}
return "";
}
public static String[] getSpoutAnvilMessages(int blockId) {
if (blockId == repairAnvilId) {
return new String[] {LocaleLoader.getString("Repair.AnvilPlaced.Spout1"), LocaleLoader.getString("Repair.AnvilPlaced.Spout2")};
}
if (blockId == salvageAnvilId) {
return new String[] {"[mcMMO] Anvil Placed", "Right click to salvage!"};
}
return new String[] {"", ""};
}
/**
* Search the inventory for an item and return the index.
*
@@ -99,30 +123,6 @@ public class Repair {
inventory.removeItem(item);
}
protected static String[] getSpoutAnvilMessages(int blockId) {
if (blockId == repairAnvilId) {
return new String[] {LocaleLoader.getString("Repair.AnvilPlaced.Spout1"), LocaleLoader.getString("Repair.AnvilPlaced.Spout2")};
}
if (blockId == salvageAnvilId) {
return new String[] {"[mcMMO] Anvil Placed", "Right click to salvage!"};
}
return new String[] {"", ""};
}
protected static String getAnvilMessage(int blockId) {
if (blockId == repairAnvilId) {
return LocaleLoader.getString("Repair.Listener.Anvil");
}
if (blockId == salvageAnvilId) {
return LocaleLoader.getString("Repair.Listener.Anvil2");
}
return "";
}
protected static Material getSalvagedItem(ItemStack inHand) {
if (ItemUtils.isDiamondTool(inHand) || ItemUtils.isDiamondArmor(inHand)) {
return Material.DIAMOND;

View File

@@ -10,10 +10,9 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent;
@@ -23,7 +22,9 @@ import com.gmail.nossr50.skills.repair.ArcaneForging.Tier;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.spout.SpoutUtils;
public class RepairManager extends SkillManager {
public RepairManager(McMMOPlayer mcMMOPlayer) {
@@ -42,16 +43,8 @@ public class RepairManager extends SkillManager {
return;
}
if (mcMMO.spoutEnabled) {
SpoutPlayer spoutPlayer = SpoutManager.getPlayer(player);
if (spoutPlayer.isSpoutCraftEnabled()) {
String[] spoutMessages = Repair.getSpoutAnvilMessages(anvilId);
spoutPlayer.sendNotification(spoutMessages[0], spoutMessages[1], Material.getMaterial(anvilId));
}
else {
player.sendMessage(Repair.getAnvilMessage(anvilId));
}
if (mcMMO.isSpoutEnabled()) {
SpoutUtils.sendRepairNotifications(player, anvilId);
}
else {
player.sendMessage(Repair.getAnvilMessage(anvilId));
@@ -65,7 +58,7 @@ public class RepairManager extends SkillManager {
Player player = getPlayer();
int itemId = item.getTypeId();
Repairable repairable = mcMMO.repairableManager.getRepairable(itemId);
Repairable repairable = mcMMO.getRepairableManager().getRepairable(itemId);
// Permissions checks on material and item types
if (!repairable.getRepairItemType().getPermissions(player)) {
@@ -193,6 +186,38 @@ public class RepairManager extends SkillManager {
}
}
/**
* Check if the player has tried to use an Anvil before.
*
* @return true if the player has confirmed using an Anvil
*/
public boolean checkConfirmation(int anvilId, boolean actualize) {
Player player = getPlayer();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
long LastUse = mcMMOPlayer.getLastAnvilUse(anvilId);
// Don't use SkillUtils.cooldownOver() here since that also accounts for the cooldown perks
if ((((LastUse + 3) * Misc.TIME_CONVERSION_FACTOR) >= System.currentTimeMillis()) || !Config.getInstance().getRepairConfirmRequired()) {
return true;
}
if (!actualize) {
return false;
}
mcMMOPlayer.actualizeLastAnvilUse(anvilId);
if (anvilId == Repair.repairAnvilId) {
player.sendMessage(LocaleLoader.getString("Skills.ConfirmOrCancel", LocaleLoader.getString("Repair.Pretty.Name")));
}
if (anvilId == Repair.salvageAnvilId) {
player.sendMessage(LocaleLoader.getString("Skills.ConfirmOrCancel", LocaleLoader.getString("Salvage.Pretty.Name")));
}
return false;
}
/**
* Gets the Arcane Forging rank
*

View File

@@ -25,7 +25,7 @@ public class SmeltingManager extends SkillManager {
}
public boolean canUseFluxMining(BlockState blockState) {
return getSkillLevel() >= Smelting.fluxMiningUnlockLevel && BlockUtils.affectedByFluxMining(blockState) && Permissions.fluxMining(getPlayer()) && !mcMMO.placeStore.isTrue(blockState);
return getSkillLevel() >= Smelting.fluxMiningUnlockLevel && BlockUtils.affectedByFluxMining(blockState) && Permissions.fluxMining(getPlayer()) && !mcMMO.getPlaceStore().isTrue(blockState);
}
public boolean canUseVanillaXpBoost() {
@@ -95,7 +95,9 @@ public class SmeltingManager extends SkillManager {
applyXpGain(Smelting.getResourceXp(resourceType));
if (Permissions.doubleDrops(player, skill) && SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Smelting.secondSmeltMaxChance, Smelting.secondSmeltMaxLevel)) {
ItemStack newResult = new ItemStack(result.getType(), result.getAmount() + 1);
ItemStack newResult = result.clone();
newResult.setAmount(result.getAmount() + 1);
return newResult;
}

View File

@@ -198,6 +198,11 @@ public class TamingManager extends SkillManager {
entity.setHealth(entity.getMaxHealth());
}
if (Permissions.renamePets(player)) {
entity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", player.getName(), StringUtils.getPrettyEntityTypeString(entity.getType())));
entity.setCustomNameVisible(true);
}
player.setItemInHand(new ItemStack(heldItem.getType(), heldItemAmount - summonAmount));
player.sendMessage(LocaleLoader.getString("Taming.Summon.Complete"));
}

View File

@@ -248,7 +248,7 @@ public final class Woodcutting {
* @param treeFellerBlocks List of blocks to be removed
*/
private static void handleBlock(BlockState blockState, List<BlockState> futureCenterBlocks, List<BlockState> treeFellerBlocks) {
if (!BlockUtils.affectedByTreeFeller(blockState) || mcMMO.placeStore.isTrue(blockState) || treeFellerBlocks.contains(blockState)) {
if (!BlockUtils.affectedByTreeFeller(blockState) || mcMMO.getPlaceStore().isTrue(blockState) || treeFellerBlocks.contains(blockState)) {
return;
}

View File

@@ -19,59 +19,7 @@ public final class BlockUtils {
* @return true if the block awards XP, false otherwise
*/
public static boolean shouldBeWatched(BlockState blockState) {
switch (blockState.getType()) {
case BROWN_MUSHROOM:
case CACTUS:
case CLAY:
case COAL_ORE:
case DIAMOND_ORE:
case DIRT:
case ENDER_STONE:
case GLOWING_REDSTONE_ORE:
case GLOWSTONE:
case GOLD_ORE:
case GRASS:
case GRAVEL:
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
case IRON_ORE:
case LAPIS_ORE:
case LOG:
case MELON_BLOCK:
case MOSSY_COBBLESTONE:
case MYCEL:
case NETHERRACK:
case OBSIDIAN:
case PUMPKIN:
case QUARTZ_ORE:
case RED_MUSHROOM:
case RED_ROSE:
case REDSTONE_ORE:
case SAND:
case SANDSTONE:
case SOUL_SAND:
case STONE:
case SUGAR_CANE_BLOCK:
case VINE:
case WATER_LILY:
case YELLOW_FLOWER:
case EMERALD_ORE:
return true;
case CARROT:
case CROPS:
case POTATO:
return blockState.getRawData() == CropState.RIPE.getData();
case NETHER_WARTS:
return ((NetherWarts) blockState.getData()).getState() == NetherWartsState.RIPE;
case COCOA:
return ((CocoaPlant) blockState.getData()).getSize() == CocoaPlantSize.LARGE;
default:
return ModUtils.getCustomBlock(blockState) != null;
}
return affectedByGigaDrillBreaker(blockState) || affectedByGreenTerra(blockState) || affectedBySuperBreaker(blockState) || isLog(blockState);
}
/**
@@ -111,17 +59,7 @@ public final class BlockUtils {
return false;
default:
int blockId = blockState.getTypeId();
if (blockId == Config.getInstance().getRepairAnvilId() || blockId == Config.getInstance().getSalvageAnvilId()) {
return false;
}
if (ModUtils.isCustomAbilityBlock(blockState)) {
return false;
}
return true;
return !isMcMMOAnvil(blockState) && !ModUtils.isCustomAbilityBlock(blockState);
}
}
@@ -214,26 +152,17 @@ public final class BlockUtils {
*/
public static Boolean affectedBySuperBreaker(BlockState blockState) {
switch (blockState.getType()) {
case COAL_ORE:
case DIAMOND_ORE:
case ENDER_STONE:
case GLOWING_REDSTONE_ORE:
case GLOWSTONE:
case GOLD_ORE:
case IRON_ORE:
case LAPIS_ORE:
case MOSSY_COBBLESTONE:
case NETHERRACK:
case OBSIDIAN:
case QUARTZ_ORE:
case REDSTONE_ORE:
case SANDSTONE:
case STONE:
case EMERALD_ORE:
return true;
default:
return ModUtils.isCustomMiningBlock(blockState);
return isOre(blockState) || ModUtils.isCustomMiningBlock(blockState);
}
}
@@ -266,16 +195,7 @@ public final class BlockUtils {
* @return true if the block should affected by Tree Feller, false otherwise
*/
public static boolean affectedByTreeFeller(BlockState blockState) {
switch (blockState.getType()) {
case LOG:
case LEAVES:
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
return true;
default:
return ModUtils.isCustomWoodcuttingBlock(blockState);
}
return isLog(blockState) || isLeaves(blockState);
}
/**
@@ -379,4 +299,16 @@ public final class BlockUtils {
return false;
}
}
/**
* Determine if a given block is an mcMMO anvil
*
* @param blockState The {@link BlockState} of the block to check
* @return true if the block is an mcMMO anvil, false otherwise
*/
private static boolean isMcMMOAnvil(BlockState blockState) {
int blockId = blockState.getTypeId();
return blockId == Config.getInstance().getRepairAnvilId() || blockId == Config.getInstance().getSalvageAnvilId();
}
}

View File

@@ -41,6 +41,11 @@ public final class ChimaeraWing {
return;
}
if (!Permissions.chimaeraWing(player)) {
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
return;
}
mcMMOPlayer = UserManager.getPlayer(player);
location = player.getLocation();
@@ -48,50 +53,48 @@ public final class ChimaeraWing {
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
long lastTeleport = mcMMOPlayer.getLastTeleport();
if (Permissions.chimaeraWing(player) && ItemUtils.isChimaeraWing(inHand)) {
if (mcMMOPlayer.getTeleportCommenceLocation() != null) {
if (mcMMOPlayer.getTeleportCommenceLocation() != null) {
return;
}
if (Config.getInstance().getChimaeraCooldown() > 0 && !SkillUtils.cooldownOver(lastTeleport * Misc.TIME_CONVERSION_FACTOR, Config.getInstance().getChimaeraCooldown(), player)) {
player.sendMessage(LocaleLoader.getString("Item.Generic.Wait", SkillUtils.calculateTimeLeft(lastTeleport * Misc.TIME_CONVERSION_FACTOR, Config.getInstance().getChimaeraCooldown(), player)));
return;
}
int recentlyhurt_cooldown = Config.getInstance().getChimaeraRecentlyHurtCooldown();
if (!SkillUtils.cooldownOver(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, player)) {
player.sendMessage(LocaleLoader.getString("Item.Injured.Wait", SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, player)));
return;
}
if (amount < Config.getInstance().getChimaeraUseCost()) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore", LocaleLoader.getString("Item.ChimaeraWing.Name")));
return;
}
if (Config.getInstance().getChimaeraPreventUseUnderground()) {
if (location.getY() < player.getWorld().getHighestBlockYAt(location)) {
player.setItemInHand(new ItemStack(getChimaeraWing(amount - Config.getInstance().getChimaeraUseCost())));
player.sendMessage(LocaleLoader.getString("Item.ChimaeraWing.Fail"));
player.setVelocity(new Vector(0, 0.5D, 0));
CombatUtils.dealDamage(player, Misc.getRandom().nextInt(player.getHealth() - 10));
mcMMOPlayer.actualizeLastTeleport();
return;
}
}
if (Config.getInstance().getChimaeraCooldown() > 0 && !SkillUtils.cooldownOver(lastTeleport * Misc.TIME_CONVERSION_FACTOR, Config.getInstance().getChimaeraCooldown(), player)) {
player.sendMessage(ChatColor.RED + "You need to wait before you can use this again! " + ChatColor.YELLOW + "(" + SkillUtils.calculateTimeLeft(lastTeleport * Misc.TIME_CONVERSION_FACTOR, Config.getInstance().getChimaeraCooldown(), player) + ")"); //TODO Locale!
return;
}
mcMMOPlayer.actualizeTeleportCommenceLocation(player);
int recentlyhurt_cooldown = Config.getInstance().getChimaeraRecentlyHurtCooldown();
long warmup = Config.getInstance().getChimaeraWarmup();
if (!SkillUtils.cooldownOver(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, player)) {
player.sendMessage(LocaleLoader.getString("Item.Injured.Wait", SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, player)));
return;
}
if (amount < Config.getInstance().getChimaeraUseCost()) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore", "Chimaera Wings")); //TODO Locale!
return;
}
if (Config.getInstance().getChimaeraPreventUseUnderground()) {
if (location.getY() < player.getWorld().getHighestBlockYAt(location)) {
player.setItemInHand(new ItemStack(getChimaeraWing(amount - Config.getInstance().getChimaeraUseCost())));
player.sendMessage(LocaleLoader.getString("Item.ChimaeraWing.Fail"));
player.setVelocity(new Vector(0, 0.5D, 0));
CombatUtils.dealDamage(player, Misc.getRandom().nextInt(player.getHealth() - 10));
mcMMOPlayer.actualizeLastTeleport();
return;
}
}
mcMMOPlayer.actualizeTeleportCommenceLocation(player);
long warmup = Config.getInstance().getChimaeraWarmup();
if (warmup > 0) {
player.sendMessage(ChatColor.GRAY + "Commencing teleport in " + ChatColor.GOLD + "(" + warmup + ")" + ChatColor.GRAY + " seconds, please stand still..."); //TODO Locale!
new ChimaeraWingWarmup(mcMMOPlayer).runTaskLater(mcMMO.p, 20 * warmup);
}
else {
chimaeraExecuteTeleport();
}
if (warmup > 0) {
player.sendMessage(LocaleLoader.getString("Teleport.Commencing", warmup));
new ChimaeraWingWarmup(mcMMOPlayer).runTaskLater(mcMMO.p, 20 * warmup);
}
else {
chimaeraExecuteTeleport();
}
}
@@ -125,11 +128,11 @@ public final class ChimaeraWing {
ItemStack itemStack = new ItemStack(ingredient, amount);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName(ChatColor.GOLD + "Chimaera Wing"); //TODO Locale!
itemMeta.setDisplayName(ChatColor.GOLD + LocaleLoader.getString("Item.ChimaeraWing.Name"));
List<String> itemLore = new ArrayList<String>();
itemLore.add("mcMMO Item");
itemLore.add(ChatColor.GRAY + "Teleports you to your bed."); //TODO Locale!
itemLore.add(LocaleLoader.getString("Item.ChimaeraWing.Lore"));
itemMeta.setLore(itemLore);
itemStack.setItemMeta(itemMeta);

View File

@@ -1,10 +1,7 @@
package com.gmail.nossr50.util;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -13,20 +10,18 @@ import com.gmail.nossr50.api.SpoutToolsAPI;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.mods.CustomArmorConfig;
import com.gmail.nossr50.config.mods.CustomToolConfig;
import com.gmail.nossr50.config.party.ItemWeightConfig;
import com.gmail.nossr50.locale.LocaleLoader;
public class ItemUtils {
private static Config configInstance = Config.getInstance();
private static boolean customToolsEnabled = configInstance.getToolModsEnabled();
private static boolean customArmorEnabled = configInstance.getArmorModsEnabled();
/**
* Checks if the item is a sword.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a sword, false otherwise
*/
public static boolean isSword(ItemStack is) {
switch (is.getType()) {
public static boolean isSword(ItemStack item) {
switch (item.getType()) {
case DIAMOND_SWORD:
case GOLD_SWORD:
case IRON_SWORD:
@@ -35,26 +30,18 @@ public class ItemUtils {
return true;
default:
if (customToolsEnabled && CustomToolConfig.getInstance().customSwordIDs.contains(is.getTypeId())) {
return true;
}
else if (mcMMO.spoutEnabled && SpoutToolsAPI.spoutSwords.contains(is)) {
return true;
}
else {
return false;
}
return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customSwordIDs.contains(item.getTypeId())) || (mcMMO.isSpoutEnabled() && SpoutToolsAPI.spoutSwords.contains(item));
}
}
/**
* Checks if the item is a hoe.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a hoe, false otherwise
*/
public static boolean isHoe(ItemStack is) {
switch (is.getType()) {
public static boolean isHoe(ItemStack item) {
switch (item.getType()) {
case DIAMOND_HOE:
case GOLD_HOE:
case IRON_HOE:
@@ -63,26 +50,18 @@ public class ItemUtils {
return true;
default:
if (customToolsEnabled && CustomToolConfig.getInstance().customHoeIDs.contains(is.getTypeId())) {
return true;
}
else if (mcMMO.spoutEnabled && SpoutToolsAPI.spoutHoes.contains(is)) {
return true;
}
else {
return false;
}
return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customHoeIDs.contains(item.getTypeId())) || (mcMMO.isSpoutEnabled() && SpoutToolsAPI.spoutHoes.contains(item));
}
}
/**
* Checks if the item is a shovel.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a shovel, false otherwise
*/
public static boolean isShovel(ItemStack is) {
switch (is.getType()) {
public static boolean isShovel(ItemStack item) {
switch (item.getType()) {
case DIAMOND_SPADE:
case GOLD_SPADE:
case IRON_SPADE:
@@ -91,26 +70,18 @@ public class ItemUtils {
return true;
default:
if (customToolsEnabled && CustomToolConfig.getInstance().customShovelIDs.contains(is.getTypeId())) {
return true;
}
else if (mcMMO.spoutEnabled && SpoutToolsAPI.spoutShovels.contains(is)) {
return true;
}
else {
return false;
}
return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customShovelIDs.contains(item.getTypeId())) || (mcMMO.isSpoutEnabled() && SpoutToolsAPI.spoutShovels.contains(item));
}
}
/**
* Checks if the item is an axe.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is an axe, false otherwise
*/
public static boolean isAxe(ItemStack is) {
switch (is.getType()) {
public static boolean isAxe(ItemStack item) {
switch (item.getType()) {
case DIAMOND_AXE:
case GOLD_AXE:
case IRON_AXE:
@@ -119,26 +90,18 @@ public class ItemUtils {
return true;
default:
if (customToolsEnabled && CustomToolConfig.getInstance().customAxeIDs.contains(is.getTypeId())) {
return true;
}
else if (mcMMO.spoutEnabled && SpoutToolsAPI.spoutAxes.contains(is)) {
return true;
}
else {
return false;
}
return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customAxeIDs.contains(item.getTypeId())) || (mcMMO.isSpoutEnabled() && SpoutToolsAPI.spoutAxes.contains(item));
}
}
/**
* Checks if the item is a pickaxe.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a pickaxe, false otherwise
*/
public static boolean isPickaxe(ItemStack is) {
switch (is.getType()) {
public static boolean isPickaxe(ItemStack item) {
switch (item.getType()) {
case DIAMOND_PICKAXE:
case GOLD_PICKAXE:
case IRON_PICKAXE:
@@ -147,138 +110,118 @@ public class ItemUtils {
return true;
default:
if (customToolsEnabled && CustomToolConfig.getInstance().customPickaxeIDs.contains(is.getTypeId())) {
return true;
}
else if (mcMMO.spoutEnabled && SpoutToolsAPI.spoutPickaxes.contains(is)) {
return true;
}
else {
return false;
}
return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customPickaxeIDs.contains(item.getTypeId())) || (mcMMO.isSpoutEnabled() && SpoutToolsAPI.spoutPickaxes.contains(item));
}
}
/**
* Checks if the item is a helmet.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a helmet, false otherwise
*/
public static boolean isHelmet(ItemStack is) {
switch (is.getType()) {
public static boolean isHelmet(ItemStack item) {
switch (item.getType()) {
case DIAMOND_HELMET:
case GOLD_HELMET:
case IRON_HELMET:
case CHAINMAIL_HELMET:
case LEATHER_HELMET:
return true;
default:
if (customArmorEnabled && CustomArmorConfig.getInstance().customHelmetIDs.contains(is.getTypeId())) {
return true;
}
return false;
return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customHelmetIDs.contains(item.getTypeId());
}
}
/**
* Checks if the item is a chestplate.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a chestplate, false otherwise
*/
public static boolean isChestplate(ItemStack is) {
switch (is.getType()) {
public static boolean isChestplate(ItemStack item) {
switch (item.getType()) {
case DIAMOND_CHESTPLATE:
case GOLD_CHESTPLATE:
case IRON_CHESTPLATE:
case CHAINMAIL_CHESTPLATE:
case LEATHER_CHESTPLATE:
return true;
default:
if (customArmorEnabled && CustomArmorConfig.getInstance().customChestplateIDs.contains(is.getTypeId())) {
return true;
}
return false;
return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customChestplateIDs.contains(item.getTypeId());
}
}
/**
* Checks if the item is a pair of pants.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a pair of pants, false otherwise
*/
public static boolean isLeggings(ItemStack is) {
switch (is.getType()) {
public static boolean isLeggings(ItemStack item) {
switch (item.getType()) {
case DIAMOND_LEGGINGS:
case GOLD_LEGGINGS:
case IRON_LEGGINGS:
case CHAINMAIL_LEGGINGS:
case LEATHER_LEGGINGS:
return true;
default:
if (customArmorEnabled && CustomArmorConfig.getInstance().customLeggingIDs.contains(is.getTypeId())) {
return true;
}
return false;
return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customLeggingIDs.contains(item.getTypeId());
}
}
/**
* Checks if the item is a pair of boots.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a pair of boots, false otherwise
*/
public static boolean isBoots(ItemStack is) {
switch (is.getType()) {
public static boolean isBoots(ItemStack item) {
switch (item.getType()) {
case DIAMOND_BOOTS:
case GOLD_BOOTS:
case IRON_BOOTS:
case CHAINMAIL_BOOTS:
case LEATHER_BOOTS:
return true;
default:
if (customArmorEnabled && CustomArmorConfig.getInstance().customBootIDs.contains(is.getTypeId())) {
return true;
}
return false;
return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customBootIDs.contains(item.getTypeId());
}
}
/**
* Checks to see if an item is a wearable armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is armor, false otherwise
*/
public static boolean isArmor(ItemStack is) {
return isHelmet(is) || isChestplate(is) || isLeggings(is) || isBoots(is);
public static boolean isArmor(ItemStack item) {
return isHelmet(item) || isChestplate(item) || isLeggings(item) || isBoots(item);
}
/**
* Checks to see if an item is a wearable armor piece.
* Checks to see if an item is a wearable *vanilla* armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is armor, false otherwise
*/
public static boolean isMinecraftArmor(ItemStack is) {
return isLeatherArmor(is) || isGoldArmor(is) || isIronArmor(is) || isDiamondArmor(is);
public static boolean isMinecraftArmor(ItemStack item) {
return isLeatherArmor(item) || isGoldArmor(item) || isIronArmor(item) || isDiamondArmor(item) || isChainmailArmor(item);
}
/**
* Checks to see if an item is a leather armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is leather armor, false otherwise
*/
public static boolean isLeatherArmor(ItemStack is) {
switch (is.getType()) {
public static boolean isLeatherArmor(ItemStack item) {
switch (item.getType()) {
case LEATHER_BOOTS:
case LEATHER_CHESTPLATE:
case LEATHER_HELMET:
@@ -293,11 +236,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a gold armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is gold armor, false otherwise
*/
public static boolean isGoldArmor(ItemStack is) {
switch (is.getType()) {
public static boolean isGoldArmor(ItemStack item) {
switch (item.getType()) {
case GOLD_BOOTS:
case GOLD_CHESTPLATE:
case GOLD_HELMET:
@@ -312,11 +255,11 @@ public class ItemUtils {
/**
* Checks to see if an item is an iron armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is iron armor, false otherwise
*/
public static boolean isIronArmor(ItemStack is) {
switch (is.getType()) {
public static boolean isIronArmor(ItemStack item) {
switch (item.getType()) {
case IRON_BOOTS:
case IRON_CHESTPLATE:
case IRON_HELMET:
@@ -331,11 +274,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a diamond armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is diamond armor, false otherwise
*/
public static boolean isDiamondArmor(ItemStack is) {
switch (is.getType()) {
public static boolean isDiamondArmor(ItemStack item) {
switch (item.getType()) {
case DIAMOND_BOOTS:
case DIAMOND_CHESTPLATE:
case DIAMOND_HELMET:
@@ -348,23 +291,42 @@ public class ItemUtils {
}
/**
* Checks to see if an item is a tool.
* Checks to see if an item is a chainmail armor piece.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is chainmail armor, false otherwise
*/
public static boolean isChainmailArmor(ItemStack item) {
switch (item.getType()) {
case CHAINMAIL_BOOTS:
case CHAINMAIL_CHESTPLATE:
case CHAINMAIL_HELMET:
case CHAINMAIL_LEGGINGS:
return true;
default:
return false;
}
}
/**
* Checks to see if an item is a *vanilla* tool.
*
* @param item Item to check
* @return true if the item is a tool, false otherwise
*/
public static boolean isMinecraftTool(ItemStack is) {
return isStoneTool(is) || isWoodTool(is) || isGoldTool(is) || isIronTool(is) || isDiamondTool(is) || isStringTool(is);
public static boolean isMinecraftTool(ItemStack item) {
return isStoneTool(item) || isWoodTool(item) || isGoldTool(item) || isIronTool(item) || isDiamondTool(item) || isStringTool(item);
}
/**
* Checks to see if an item is a stone tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a stone tool, false otherwise
*/
public static boolean isStoneTool(ItemStack is) {
switch (is.getType()) {
public static boolean isStoneTool(ItemStack item) {
switch (item.getType()) {
case STONE_AXE:
case STONE_HOE:
case STONE_PICKAXE:
@@ -380,11 +342,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a wooden tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a wooden tool, false otherwise
*/
public static boolean isWoodTool(ItemStack is) {
switch (is.getType()) {
public static boolean isWoodTool(ItemStack item) {
switch (item.getType()) {
case WOOD_AXE:
case WOOD_HOE:
case WOOD_PICKAXE:
@@ -400,11 +362,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a string tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a string tool, false otherwise
*/
public static boolean isStringTool(ItemStack is) {
switch (is.getType()) {
public static boolean isStringTool(ItemStack item) {
switch (item.getType()) {
case BOW:
case CARROT_STICK:
case FISHING_ROD:
@@ -418,11 +380,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a gold tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a stone tool, false otherwise
*/
public static boolean isGoldTool(ItemStack is) {
switch (is.getType()) {
public static boolean isGoldTool(ItemStack item) {
switch (item.getType()) {
case GOLD_AXE:
case GOLD_HOE:
case GOLD_PICKAXE:
@@ -438,11 +400,11 @@ public class ItemUtils {
/**
* Checks to see if an item is an iron tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is an iron tool, false otherwise
*/
public static boolean isIronTool(ItemStack is) {
switch (is.getType()) {
public static boolean isIronTool(ItemStack item) {
switch (item.getType()) {
case BUCKET:
case FLINT_AND_STEEL:
case IRON_AXE:
@@ -461,11 +423,11 @@ public class ItemUtils {
/**
* Checks to see if an item is a diamond tool.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a diamond tool, false otherwise
*/
public static boolean isDiamondTool(ItemStack is) {
switch (is.getType()) {
public static boolean isDiamondTool(ItemStack item) {
switch (item.getType()) {
case DIAMOND_AXE:
case DIAMOND_HOE:
case DIAMOND_PICKAXE:
@@ -481,16 +443,25 @@ public class ItemUtils {
/**
* Checks to see if an item is enchantable.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is enchantable, false otherwise
*/
public static boolean isEnchantable(ItemStack is) {
Material type = is.getType();
return isArmor(is) || isSword(is) || isAxe(is) || isShovel(is) || isPickaxe(is) || type == Material.SHEARS || type == Material.FISHING_ROD || type == Material.CARROT_STICK || type == Material.FLINT_AND_STEEL || type == Material.BOW;
public static boolean isEnchantable(ItemStack item) {
switch (item.getType()) {
case SHEARS:
case FISHING_ROD:
case CARROT_STICK:
case BOW:
case FLINT_AND_STEEL:
return true;
default:
return isArmor(item) || isSword(item) || isAxe(item) || isShovel(item) || isPickaxe(item);
}
}
public static boolean isSmeltable(ItemStack itemStack) {
switch (itemStack.getType()) {
public static boolean isSmeltable(ItemStack item) {
switch (item.getType()) {
case COAL_ORE:
case DIAMOND_ORE:
case GLOWING_REDSTONE_ORE:
@@ -499,6 +470,7 @@ public class ItemUtils {
case LAPIS_ORE:
case REDSTONE_ORE:
case EMERALD_ORE:
case QUARTZ_ORE:
return true;
default:
@@ -506,22 +478,19 @@ public class ItemUtils {
}
}
public static boolean isSmelted(ItemStack itemStack) {
switch (itemStack.getType()) {
public static boolean isSmelted(ItemStack item) {
switch (item.getType()) {
case COAL:
case DIAMOND:
case REDSTONE:
case GOLD_INGOT:
case IRON_INGOT:
case EMERALD:
case QUARTZ:
return true;
case INK_SACK:
if (itemStack.getData().getData() == DyeColor.BLUE.getDyeData()) {
return true;
}
return false;
return item.getData().getData() == DyeColor.BLUE.getDyeData();
default:
return false;
@@ -534,18 +503,18 @@ public class ItemUtils {
* @param item Item that will get shared
* @return True if the item can be shared.
*/
public static boolean isShareable(ItemStack is) {
return isMiningDrop(is) || isWoodcuttingDrop(is) || isMobDrop(is) || isHerbalismDrop(is);
public static boolean isShareable(ItemStack item) {
return isMiningDrop(item) || isWoodcuttingDrop(item) || isMobDrop(item) || isHerbalismDrop(item) || isMiscDrop(item);
}
/**
* Checks to see if an item is a mining drop.
*
* @param is Item to check
* @param item Item to check
* @return true if the item is a mining drop, false otherwise
*/
public static boolean isMiningDrop(ItemStack is) {
switch (is.getType()) {
public static boolean isMiningDrop(ItemStack item) {
switch (item.getType()) {
case COAL:
case COAL_ORE:
case DIAMOND:
@@ -555,25 +524,29 @@ public class ItemUtils {
case GOLD_ORE:
case IRON_ORE:
case LAPIS_ORE:
case REDSTONE_ORE:
case REDSTONE_ORE: // Should we also have Glowing Redstone Ore here?
case REDSTONE:
case GLOWSTONE_DUST:
case GLOWSTONE_DUST: // Should we also have Glowstone here?
case QUARTZ:
case QUARTZ_ORE:
return true;
case INK_SACK:
if (is.getData().getData() == DyeColor.BLUE.getDyeData()) {
return true;
}
return false;
return item.getData().getData() == DyeColor.BLUE.getDyeData();
default:
return false;
}
}
public static boolean isHerbalismDrop(ItemStack is) {
switch (is.getType()) {
/**
* Checks to see if an item is a herbalism drop.
*
* @param item Item to check
* @return true if the item is a herbalism drop, false otherwise
*/
public static boolean isHerbalismDrop(ItemStack item) {
switch (item.getType()) {
case WHEAT:
case SEEDS:
case CARROT_ITEM:
@@ -586,21 +559,29 @@ public class ItemUtils {
case CACTUS:
case SUGAR_CANE:
case MELON:
case MELON_SEEDS:
case PUMPKIN:
case PUMPKIN_SEEDS:
case WATER_LILY:
case VINE:
return true;
case INK_SACK:
return is.getData().getData() == DyeColor.BROWN.getDyeData();
return item.getData().getData() == DyeColor.BROWN.getDyeData();
default:
return false;
}
}
public static boolean isMobDrop(ItemStack is) {
switch (is.getType()) {
/**
* Checks to see if an item is a mob drop.
*
* @param item Item to check
* @return true if the item is a mob drop, false otherwise
*/
public static boolean isMobDrop(ItemStack item) {
switch (item.getType()) {
case STRING:
case FEATHER:
case RAW_CHICKEN:
@@ -611,7 +592,7 @@ public class ItemUtils {
case PORK:
case GRILLED_PORK:
case WOOL:
case RED_ROSE:
case RED_ROSE: // Not sure we should include this, as it will also trigger from herbalism
case IRON_INGOT:
case SNOW_BALL:
case BLAZE_ROD:
@@ -624,7 +605,7 @@ public class ItemUtils {
case ARROW:
case SLIME_BALL:
case NETHER_STAR:
case COAL:
case COAL: // Not sure we should include this, as it will also trigger when mining
case ROTTEN_FLESH:
case GOLD_NUGGET:
case EGG:
@@ -635,8 +616,14 @@ public class ItemUtils {
}
}
public static boolean isWoodcuttingDrop(ItemStack is) {
switch (is.getType()) {
/**
* Checks to see if an item is a woodcutting drop.
*
* @param item Item to check
* @return true if the item is a woodcutting drop, false otherwise
*/
public static boolean isWoodcuttingDrop(ItemStack item) {
switch (item.getType()) {
case LOG:
case LEAVES:
case SAPLING:
@@ -648,31 +635,31 @@ public class ItemUtils {
}
}
public static boolean isMcMMOItem(ItemStack is) {
if (!is.hasItemMeta()) {
return false;
}
ItemMeta itemMeta = is.getItemMeta();
if (itemMeta.hasLore()) {
List<String> itemLore = itemMeta.getLore();
if (itemLore.contains("mcMMO Item")) {
return true;
}
}
return false;
/**
* Checks to see if an item is a miscellaneous drop. These items are read from the config file
*
* @param item Item to check
* @return true if the item is a miscellaneous drop, false otherwise
*/
public static boolean isMiscDrop(ItemStack item) {
return ItemWeightConfig.getInstance().getMiscItems().contains(item.getType());
}
public static boolean isChimaeraWing(ItemStack is) {
if (!isMcMMOItem(is)) {
public static boolean isMcMMOItem(ItemStack item) {
if (!item.hasItemMeta()) {
return false;
}
ItemMeta itemMeta = is.getItemMeta();
if (itemMeta.hasDisplayName() && itemMeta.getDisplayName().equals(ChatColor.GOLD + "Chimaera Wing")) { //TODO Get localized name
return true;
ItemMeta itemMeta = item.getItemMeta();
return itemMeta.hasLore() && itemMeta.getLore().contains("mcMMO Item");
}
public static boolean isChimaeraWing(ItemStack item) {
if (!isMcMMOItem(item)) {
return false;
}
return false;
ItemMeta itemMeta = item.getItemMeta();
return itemMeta.hasDisplayName() && itemMeta.getDisplayName().equals(ChatColor.GOLD + LocaleLoader.getString("Item.ChimaeraWing.Name"));
}
}

View File

@@ -1,16 +1,17 @@
package com.gmail.nossr50.util;
import java.util.Collection;
import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
@@ -19,7 +20,6 @@ import com.gmail.nossr50.util.spout.SpoutUtils;
public final class Misc {
private static Random random = new Random();
public static boolean isSpawnerXPEnabled = Config.getInstance().getExperienceGainsMobspawnersEnabled();
public static final int PLAYER_RESPAWN_COOLDOWN_SECONDS = 5;
public static final int TIME_CONVERSION_FACTOR = 1000;
public static final double SKILL_MESSAGE_MAX_SENDING_DISTANCE = 10.0;
@@ -27,21 +27,28 @@ public final class Misc {
// Sound Pitches & Volumes from CB
public static final float ANVIL_USE_PITCH = 0.3F; // Not in CB directly, I went off the place sound values
public static final float ANVIL_USE_VOLUME = 1.0F; // Not in CB directly, I went off the place sound values
public static final float FIZZ_PITCH = 2.6F + (Misc.getRandom().nextFloat() - Misc.getRandom().nextFloat()) * 0.8F;
public static final float FIZZ_VOLUME = 0.5F;
public static final float POP_PITCH = ((getRandom().nextFloat() - getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F;
public static final float POP_VOLUME = 0.2F;
public static final float BAT_VOLUME = 1.0F;
public static final float BAT_PITCH = 0.6F;
public static final float GHAST_VOLUME = 1.0F;
private Misc() {};
public static boolean isNPCEntity(Entity entity) {
if (entity == null || entity.hasMetadata("NPC")) {
return true;
}
public static float getFizzPitch() {
return 2.6F + (getRandom().nextFloat() - getRandom().nextFloat()) * 0.8F;
}
return false;
public static float getPopPitch() {
return ((getRandom().nextFloat() - getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F;
}
public static float getGhastPitch() {
return (getRandom().nextFloat() - getRandom().nextFloat()) * 0.2F + 1.0F;
}
public static boolean isNPCEntity(Entity entity) {
return (entity == null || entity.hasMetadata("NPC") || (mcMMO.isCombatTagEnabled() && entity instanceof HumanEntity && ((HumanEntity) entity).getName().contains("PvpLogger")));
}
/**
@@ -88,11 +95,13 @@ public final class Misc {
return false;
}
if (first.distanceSquared(second) < (maxDistance * maxDistance)) {
return true;
}
return first.distanceSquared(second) < (maxDistance * maxDistance);
}
return false;
public static void dropItems(Location location, Collection<ItemStack> drops) {
for (ItemStack drop : drops) {
dropItem(location, drop);
}
}
/**
@@ -145,7 +154,6 @@ public final class Misc {
* @param itemStack The item to drop
*/
public static void dropItem(Location location, ItemStack itemStack) {
if (itemStack.getType() == Material.AIR) {
return;
}
@@ -158,12 +166,7 @@ public final class Misc {
return;
}
Item newItem = location.getWorld().dropItemNaturally(location, itemStack);
ItemStack cloned = itemStack.clone();
cloned.setAmount(newItem.getItemStack().getAmount());
newItem.setItemStack(cloned);
location.getWorld().dropItemNaturally(location, itemStack);
}
public static void profileCleanup(String playerName) {
@@ -182,7 +185,7 @@ public final class Misc {
if (player.isOnline()) {
UserManager.addUser(player);
if (mcMMO.spoutEnabled) {
if (mcMMO.isSpoutEnabled()) {
SpoutUtils.reloadSpoutPlayer(player);
}
}
@@ -190,8 +193,12 @@ public final class Misc {
}
public static void resendChunkRadiusAt(Player player, int radius) {
for (int x = player.getLocation().getChunk().getX() - radius; x < player.getLocation().getChunk().getX() + radius; x++) {
for (int z = player.getLocation().getChunk().getZ() - radius; z < player.getLocation().getChunk().getZ() + radius; z++) {
Chunk chunk = player.getLocation().getChunk();
int chunkX = chunk.getX();
int chunkZ = chunk.getZ();
for (int x = chunkX - radius; x < chunkX + radius; x++) {
for (int z = chunkZ - radius; z < chunkZ + radius; z++) {
player.getWorld().refreshChunk(x, z);
}
}

View File

@@ -0,0 +1,152 @@
package com.gmail.nossr50.util;
import org.bukkit.ChatColor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.metadata.FixedMetadataValue;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
import com.gmail.nossr50.util.player.UserManager;
public final class MobHealthbarUtils {
private MobHealthbarUtils() {};
/**
* Fix issues with death messages caused by the mob healthbars.
*
* @param deathMessage The original death message
* @param player The player who died
* @return the fixed death message
*/
public static String fixDeathMessage(String deathMessage, Player player) {
EntityDamageEvent lastDamageCause = player.getLastDamageCause();
String replaceString = lastDamageCause instanceof EntityDamageByEntityEvent ? StringUtils.getPrettyEntityTypeString(((EntityDamageByEntityEvent) lastDamageCause).getDamager().getType()) : "a mob";
return deathMessage.replaceAll("(?:\u00A7(?:[0-9A-FK-ORa-fk-or]){1}(?:[\u2764\u25A0]{1,10})){1,2}", replaceString);
}
/**
* Handle the creation of mob healthbars.
*
* @param profile The
* @param target
* @param damage
*/
public static void handleMobHealthbars(Player player, LivingEntity target, int damage) {
if (!Permissions.mobHealthDisplay(player)) {
return;
}
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
if (profile.getMobHealthbarType() == null) {
profile.setMobHealthbarType(Config.getInstance().getMobHealthbarDefault());
}
if (profile.getMobHealthbarType() == MobHealthbarType.DISABLED) {
return;
}
String oldName = target.getCustomName();
if (oldName == null) {
oldName = "";
}
else if (oldName.equalsIgnoreCase(AdvancedConfig.getInstance().getKrakenName())) {
return;
}
boolean oldNameVisible = target.isCustomNameVisible();
String newName = createHealthDisplay(profile, target, damage);
target.setCustomName(newName);
target.setCustomNameVisible(true);
int displayTime = Config.getInstance().getMobHealthbarTime();
if (displayTime != -1) {
boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName));
if (updateName) {
target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, oldName));
target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, oldNameVisible));
}
else if (!target.hasMetadata(mcMMO.customNameKey)) {
target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, ""));
target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, false));
}
new MobHealthDisplayUpdaterTask(target).runTaskLater(mcMMO.p, displayTime * 20); // Clear health display after 3 seconds
}
}
private static String createHealthDisplay(PlayerProfile profile, LivingEntity entity, int damage) {
int maxHealth = entity.getMaxHealth();
int currentHealth = Math.max(entity.getHealth() - damage, 0);
double healthPercentage = (currentHealth / (double) maxHealth) * 100.0D;
int fullDisplay = 0;
ChatColor color = ChatColor.BLACK;
String symbol = "";
switch (profile.getMobHealthbarType()) {
case HEARTS:
fullDisplay = Math.min(maxHealth / 2, 10);
color = ChatColor.DARK_RED;
symbol = "";
break;
case BAR:
fullDisplay = 10;
if (healthPercentage >= 85) {
color = ChatColor.DARK_GREEN;
}
else if (healthPercentage >= 70) {
color = ChatColor.GREEN;
}
else if (healthPercentage >= 55) {
color = ChatColor.GOLD;
}
else if (healthPercentage >= 40) {
color = ChatColor.YELLOW;
}
else if (healthPercentage >= 25) {
color = ChatColor.RED;
}
else if (healthPercentage >= 0) {
color = ChatColor.DARK_RED;
}
symbol = "";
break;
default:
return null;
}
int coloredDisplay = (int) (fullDisplay * (healthPercentage / 100.0D));
int grayDisplay = fullDisplay - coloredDisplay;
String healthbar = color + "";
for (int i = 0; i < coloredDisplay; i++) {
healthbar += symbol;
}
healthbar += ChatColor.GRAY;
for (int i = 0; i < grayDisplay; i++) {
healthbar += symbol;
}
return healthbar;
}
}

View File

@@ -62,7 +62,7 @@ public final class Motd {
* @param player Target player
*/
public static void displayXpPerks(Player player) {
int perkAmount = PerksUtils.handleXpPerks(player, 1);
float perkAmount = PerksUtils.handleXpPerks(player, 1);
if (perkAmount > 1) {
player.sendMessage(perkPrefix + LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Perks.xp.name"), LocaleLoader.getString("Perks.xp.desc", perkAmount)));

View File

@@ -27,6 +27,7 @@ public final class Permissions {
/* BYPASS */
public static boolean hardcoreBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.hardcoremode"); }
public static boolean arcaneBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.arcanebypass"); }
public static boolean krakenBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.kraken"); }
/* CHAT */
public static boolean partyChat(Permissible permissible) { return permissible.hasPermission("mcmmo.chat.partychat"); }
@@ -49,6 +50,9 @@ public final class Permissions {
public static boolean inspectFar(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.far")); }
public static boolean inspectOffline(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.offline")); }
public static boolean kraken(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.kraken"); }
public static boolean krakenOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.kraken.others"); }
public static boolean mcability(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability")); }
public static boolean mcabilityOthers(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability.others")); }
@@ -142,6 +146,7 @@ public final class Permissions {
/* FISHING */
public static boolean fishermansDiet(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.fishermansdiet"); }
public static boolean fishingTreasureHunter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.treasures"); }
public static boolean iceFishing(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.icefishing"); }
public static boolean magicHunter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.magic"); }
public static boolean masterAngler(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.masterangler"); }
public static boolean shake(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.shakemob"); }
@@ -191,6 +196,7 @@ public final class Permissions {
/* TAMING */
public static boolean beastLore(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.beastlore"); }
public static boolean callOfTheWild(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.callofthewild"); }
public static boolean renamePets(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.callofthewild_renamepets"); }
public static boolean environmentallyAware(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.environmentallyaware"); }
public static boolean fastFoodService(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.fastfoodservice"); }
public static boolean gore(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.gore"); }

View File

@@ -34,7 +34,7 @@ public class BlockStoreConversionZDirectory implements Runnable {
this.world = world;
this.scheduler = mcMMO.p.getServer().getScheduler();
this.manager = new HashChunkletManager();
this.newManager = (HashChunkManager) mcMMO.placeStore;
this.newManager = (HashChunkManager) mcMMO.getPlaceStore();
this.dataDir = dataDir;
this.xDir = xDir;

View File

@@ -6,11 +6,13 @@ import java.util.List;
import org.bukkit.command.PluginCommand;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.commands.KrakenCommand;
import com.gmail.nossr50.commands.McabilityCommand;
import com.gmail.nossr50.commands.McgodCommand;
import com.gmail.nossr50.commands.McmmoCommand;
import com.gmail.nossr50.commands.McnotifyCommand;
import com.gmail.nossr50.commands.McrefreshCommand;
import com.gmail.nossr50.commands.McscoreboardCommand;
import com.gmail.nossr50.commands.MobhealthCommand;
import com.gmail.nossr50.commands.XprateCommand;
import com.gmail.nossr50.commands.chat.AdminChatCommand;
@@ -56,7 +58,7 @@ public final class CommandRegistrationManager {
private static String permissionsMessage = LocaleLoader.getString("mcMMO.NoPermission");
public static void registerSkillCommands() {
private static void registerSkillCommands() {
for (SkillType skill : SkillType.values()) {
String commandName = skill.toString().toLowerCase();
String localizedName = SkillUtils.getSkillName(skill).toLowerCase();
@@ -129,7 +131,7 @@ public final class CommandRegistrationManager {
}
}
public static void registerAddlevelsCommand() {
private static void registerAddlevelsCommand() {
PluginCommand command = mcMMO.p.getCommand("addlevels");
command.setDescription(LocaleLoader.getString("Commands.Description.addlevels"));
command.setPermission("mcmmo.commands.addlevels;mcmmo.commands.addlevels.others");
@@ -138,7 +140,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new AddlevelsCommand());
}
public static void registerAddxpCommand() {
private static void registerAddxpCommand() {
PluginCommand command = mcMMO.p.getCommand("addxp");
command.setDescription(LocaleLoader.getString("Commands.Description.addxp"));
command.setPermission("mcmmo.commands.addxp;mcmmo.commands.addxp.others");
@@ -147,7 +149,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new AddxpCommand());
}
public static void registerMcgodCommand() {
private static void registerMcgodCommand() {
PluginCommand command = mcMMO.p.getCommand("mcgod");
command.setDescription(LocaleLoader.getString("Commands.Description.mcgod"));
command.setPermission("mcmmo.commands.mcgod;mcmmo.commands.mcgod.others");
@@ -156,7 +158,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McgodCommand());
}
public static void registerMcrefreshCommand() {
private static void registerMcrefreshCommand() {
PluginCommand command = mcMMO.p.getCommand("mcrefresh");
command.setDescription(LocaleLoader.getString("Commands.Description.mcrefresh"));
command.setPermission("mcmmo.commands.mcrefresh;mcmmo.commands.mcrefresh.others");
@@ -165,7 +167,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McrefreshCommand());
}
public static void registerMmoeditCommand() {
private static void registerMmoeditCommand() {
PluginCommand command = mcMMO.p.getCommand("mmoedit");
command.setDescription(LocaleLoader.getString("Commands.Description.mmoedit"));
command.setPermission("mcmmo.commands.mmoedit;mcmmo.commands.mmoedit.others");
@@ -174,7 +176,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new MmoeditCommand());
}
public static void registerSkillresetCommand() {
private static void registerSkillresetCommand() {
PluginCommand command = mcMMO.p.getCommand("skillreset");
command.setDescription(LocaleLoader.getString("Commands.Description.skillreset"));
command.setPermission("mcmmo.commands.skillreset;mcmmo.commands.skillreset.others"); // Only need the main ones, not the individual skill ones
@@ -183,7 +185,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new SkillresetCommand());
}
public static void registerXprateCommand() {
private static void registerXprateCommand() {
List<String> aliasList = new ArrayList<String>();
aliasList.add("mcxprate");
@@ -197,7 +199,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new XprateCommand());
}
public static void registerInspectCommand() {
private static void registerInspectCommand() {
PluginCommand command = mcMMO.p.getCommand("inspect");
command.setDescription(LocaleLoader.getString("Commands.Description.inspect"));
command.setPermission("mcmmo.commands.inspect;mcmmo.commands.inspect.far;mcmmo.commands.inspect.offline");
@@ -206,7 +208,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new InspectCommand());
}
public static void registerMcabilityCommand() {
private static void registerMcabilityCommand() {
PluginCommand command = mcMMO.p.getCommand("mcability");
command.setDescription(LocaleLoader.getString("Commands.Description.mcability"));
command.setPermission("mcmmo.commands.mcability;mcmmo.commands.mcability.others");
@@ -215,7 +217,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McabilityCommand());
}
public static void registerMcmmoCommand() {
private static void registerMcmmoCommand() {
PluginCommand command = mcMMO.p.getCommand("mcmmo");
command.setDescription(LocaleLoader.getString("Commands.Description.mcmmo"));
command.setPermission("mcmmo.commands.mcmmo.description;mcmmo.commands.mcmmo.help");
@@ -225,7 +227,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McmmoCommand());
}
public static void registerMcrankCommand() {
private static void registerMcrankCommand() {
PluginCommand command = mcMMO.p.getCommand("mcrank");
command.setDescription(LocaleLoader.getString("Commands.Description.mcrank"));
command.setPermission("mcmmo.commands.mcrank;mcmmo.commands.mcrank.others;mcmmo.commands.mcrank.others.far;mcmmo.commands.mcrank.others.offline");
@@ -234,7 +236,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McrankCommand());
}
public static void registerMcstatsCommand() {
private static void registerMcstatsCommand() {
PluginCommand command = mcMMO.p.getCommand("mcstats");
command.setDescription(LocaleLoader.getString("Commands.Description.mcstats"));
command.setPermission("mcmmo.commands.mcstats");
@@ -243,7 +245,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McstatsCommand());
}
public static void registerMctopCommand() {
private static void registerMctopCommand() {
PluginCommand command = mcMMO.p.getCommand("mctop");
command.setDescription(LocaleLoader.getString("Commands.Description.mctop"));
command.setPermission("mcmmo.commands.mctop"); // Only need the main one, not the individual skill ones
@@ -252,31 +254,34 @@ public final class CommandRegistrationManager {
command.setExecutor(new MctopCommand());
}
public static void registerMcpurgeCommand() {
private static void registerMcpurgeCommand() {
PluginCommand command = mcMMO.p.getCommand("mcpurge");
command.setDescription(LocaleLoader.getString("Commands.Description.mcpurge", Config.getInstance().getOldUsersCutoff()));
command.setPermission("mcmmo.commands.mcpurge");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mcpurge"));
command.setExecutor(new McpurgeCommand());
}
public static void registerMcremoveCommand() {
private static void registerMcremoveCommand() {
PluginCommand command = mcMMO.p.getCommand("mcremove");
command.setDescription(LocaleLoader.getString("Commands.Description.mcremove"));
command.setPermission("mcmmo.commands.mcremove");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "mcremove", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">"));
command.setExecutor(new McremoveCommand());
}
public static void registerMmoupdateCommand() {
private static void registerMmoupdateCommand() {
PluginCommand command = mcMMO.p.getCommand("mmoupdate");
command.setDescription(LocaleLoader.getString("Commands.Description.mmoupdate"));
command.setPermission("mcmmo.commands.mmoupdate");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mmoupdate"));
command.setExecutor(new MmoupdateCommand());
}
public static void registerAdminChatCommand() {
private static void registerAdminChatCommand() {
PluginCommand command = mcMMO.p.getCommand("adminchat");
command.setDescription(LocaleLoader.getString("Commands.Description.adminchat"));
command.setPermission("mcmmo.chat.adminchat");
@@ -287,7 +292,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new AdminChatCommand());
}
public static void registerPartyChatCommand() {
private static void registerPartyChatCommand() {
PluginCommand command = mcMMO.p.getCommand("partychat");
command.setDescription(LocaleLoader.getString("Commands.Description.partychat"));
command.setPermission("mcmmo.chat.partychat;mcmmo.commands.party");
@@ -298,7 +303,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new PartyChatCommand());
}
public static void registerMchudCommand() {
private static void registerMchudCommand() {
PluginCommand command = mcMMO.p.getCommand("mchud");
command.setDescription(LocaleLoader.getString("Commands.Description.mchud"));
command.setPermission("mcmmo.commands.mchud");
@@ -307,7 +312,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new MchudCommand());
}
public static void registerXplockCommand() {
private static void registerXplockCommand() {
PluginCommand command = mcMMO.p.getCommand("xplock");
command.setDescription(LocaleLoader.getString("Commands.Description.xplock"));
command.setPermission("mcmmo.commands.xplock");
@@ -318,7 +323,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new XplockCommand());
}
public static void registerPartyCommand() {
private static void registerPartyCommand() {
PluginCommand command = mcMMO.p.getCommand("party");
command.setDescription(LocaleLoader.getString("Commands.Description.party"));
command.setPermission("mcmmo.commands.party;mcmmo.commands.party.accept;mcmmo.commands.party.create;mcmmo.commands.party.disband;" +
@@ -329,7 +334,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new PartyCommand());
}
public static void registerPtpCommand() {
private static void registerPtpCommand() {
PluginCommand command = mcMMO.p.getCommand("ptp");
command.setDescription(LocaleLoader.getString("Commands.Description.ptp"));
command.setPermission("mcmmo.commands.ptp"); // Only need the main one, not the individual ones for toggle/accept/acceptall
@@ -339,7 +344,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new PtpCommand());
}
public static void registerHardcoreCommand() {
private static void registerHardcoreCommand() {
PluginCommand command = mcMMO.p.getCommand("hardcore");
command.setDescription(LocaleLoader.getString("Commands.Description.hardcore"));
command.setPermission("mcmmo.commands.hardcore;mcmmo.commands.hardcore.toggle;mcmmo.commands.hardcore.modify");
@@ -349,7 +354,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new HardcoreCommand());
}
public static void registerVampirismCommand() {
private static void registerVampirismCommand() {
PluginCommand command = mcMMO.p.getCommand("vampirism");
command.setDescription(LocaleLoader.getString("Commands.Description.vampirism"));
command.setPermission("mcmmo.commands.vampirism;mcmmo.commands.vampirism.toggle;mcmmo.commands.vampirism.modify");
@@ -359,7 +364,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new VampirismCommand());
}
public static void registerMcnotifyCommand() {
private static void registerMcnotifyCommand() {
PluginCommand command = mcMMO.p.getCommand("mcnotify");
command.setDescription(LocaleLoader.getString("Commands.Description.mcnotify"));
command.setPermission("mcmmo.commands.mcnotify");
@@ -368,7 +373,7 @@ public final class CommandRegistrationManager {
command.setExecutor(new McnotifyCommand());
}
public static void registerMobhealthCommand() {
private static void registerMobhealthCommand() {
PluginCommand command = mcMMO.p.getCommand("mobhealth");
command.setDescription("Change the style of the mob healthbar"); //TODO: Localize
command.setPermission("mcmmo.commands.mobhealth");
@@ -376,4 +381,72 @@ public final class CommandRegistrationManager {
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "mobhealth", "<DISABLED | HEARTS | BAR>"));
command.setExecutor(new MobhealthCommand());
}
private static void registerMcscoreboardCommand() {
PluginCommand command = mcMMO.p.getCommand("mcscoreboard");
command.setDescription("Change the current mcMMO scoreboard being displayed"); //TODO: Localize
command.setPermission("mcmmo.commands.mcscoreboard");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "mcscoreboard", "<CLEAR | RANK | STATS | TOP>"));
command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.3", "mcscoreboard", "top", "[" + LocaleLoader.getString("Commands.Usage.Skill") + "]", "[" + LocaleLoader.getString("Commands.Usage.Page") + "]"));
command.setExecutor(new McscoreboardCommand());
}
private static void registerKrakenCommand() {
PluginCommand command = mcMMO.p.getCommand("kraken");
command.setDescription("Unleash the kraken!"); //TODO: Localize
command.setPermission("mcmmo.commands.kraken;mcmmo.commands.kraken.others");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "kraken", "[" + LocaleLoader.getString("Commands.Usage.Player") + "]"));
command.setExecutor(new KrakenCommand());
}
public static void registerCommands() {
// Generic Commands
registerKrakenCommand();
registerMcabilityCommand();
registerMcgodCommand();
registerMcmmoCommand();
registerMcnotifyCommand();
registerMcrefreshCommand();
registerMcscoreboardCommand();
registerMobhealthCommand();
registerXprateCommand();
// Chat Commands
registerPartyChatCommand();
registerAdminChatCommand();
// Database Commands
registerMcpurgeCommand();
registerMcremoveCommand();
registerMmoupdateCommand();
// Experience Commands
registerAddlevelsCommand();
registerAddxpCommand();
registerMmoeditCommand();
registerSkillresetCommand();
// Hardcore Commands
registerHardcoreCommand();
registerVampirismCommand();
// Party Commands
registerPartyCommand();
registerPtpCommand();
// Player Commands
registerInspectCommand();
registerMcrankCommand();
registerMcstatsCommand();
registerMctopCommand();
// Skill Commands
registerSkillCommands();
// Spout Commands
registerXplockCommand();
registerMchudCommand();
}
}

View File

@@ -1,7 +1,5 @@
package com.gmail.nossr50.util.player;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -17,20 +15,6 @@ public final class UserManager {
private UserManager() {};
/**
* Load users.
*/
public static void loadUsers() {
new File(mcMMO.getFlatFileDirectory()).mkdir();
try {
new File(mcMMO.getUsersFilePath()).createNewFile();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Add a new user.
*

View File

@@ -0,0 +1,350 @@
package com.gmail.nossr50.util.scoreboards;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.runnables.scoreboards.ScoreboardChangeTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
public class ScoreboardManager {
private static final Map<String, Scoreboard> PLAYER_SCOREBOARDS = new HashMap<String, Scoreboard>();
private static final Scoreboard GLOBAL_STATS_SCOREBOARD = mcMMO.p.getServer().getScoreboardManager().getNewScoreboard();
private final static String PLAYER_STATS_HEADER = "mcMMO Stats";
private final static String PLAYER_RANK_HEADER = "mcMMO Rankings";
private final static String PLAYER_INSPECT_HEADER = "mcMMO Stats: ";
private final static String POWER_LEVEL_HEADER = "Power Level";
private final static List<String> SCOREBOARD_TASKS = new ArrayList<String>();
public static void setupPlayerScoreboard(String playerName) {
if (PLAYER_SCOREBOARDS.containsKey(playerName)) {
return;
}
PLAYER_SCOREBOARDS.put(playerName, mcMMO.p.getServer().getScoreboardManager().getNewScoreboard());
}
public static void enablePowerLevelDisplay(Player player) {
if (!Config.getInstance().getPowerLevelsEnabled()) {
return;
}
Scoreboard scoreboard = player.getScoreboard();
Objective objective;
if (scoreboard.getObjective(DisplaySlot.BELOW_NAME) == null) {
objective = scoreboard.registerNewObjective(POWER_LEVEL_HEADER, "dummy");
objective.getScore(player).setScore(UserManager.getPlayer(player).getPowerLevel());
objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
}
else {
objective = scoreboard.getObjective(POWER_LEVEL_HEADER);
if (scoreboard.getObjective(POWER_LEVEL_HEADER) != null) {
objective.getScore(player).setScore(UserManager.getPlayer(player).getPowerLevel());
}
else {
mcMMO.p.debug("Another plugin is using this scoreboard slot, so power levels cannot be enabled."); //TODO: Locale
}
}
}
public static void enablePlayerSkillScoreboard(McMMOPlayer mcMMOPlayer, SkillType skill) {
Player player = mcMMOPlayer.getPlayer();
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(SkillUtils.getSkillName(skill));
if (objective == null) {
objective = newScoreboard.registerNewObjective(SkillUtils.getSkillName(skill), "dummy");
}
updatePlayerSkillScores(mcMMOPlayer.getProfile(), skill, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getSkillScoreboardTime());
}
public static void enablePlayerStatsScoreboard(McMMOPlayer mcMMOPlayer) {
Player player = mcMMOPlayer.getPlayer();
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_STATS_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_STATS_HEADER, "dummy");
}
updatePlayerStatsScores(mcMMOPlayer, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcstatsScoreboardTime());
}
public static void enablePlayerRankScoreboard(Player player) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_RANK_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_RANK_HEADER, "dummy");
}
updatePlayerRankScores(player, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcrankScoreboardTime());
}
public static void enablePlayerRankScoreboardOthers(Player player, String targetName) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_RANK_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_RANK_HEADER, "dummy");
}
updatePlayerRankOthersScores(targetName, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcrankScoreboardTime());
}
public static void enablePlayerInspectScoreboardOnline(Player player, McMMOPlayer mcMMOTarget) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_INSPECT_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_INSPECT_HEADER, "dummy");
}
updatePlayerInspectOnlineScores(mcMMOTarget, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getInspectScoreboardTime());
}
public static void enablePlayerInspectScoreboardOffline(Player player, PlayerProfile targetProfile) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_INSPECT_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_INSPECT_HEADER, "dummy");
}
updatePlayerInspectOfflineScores(targetProfile, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getInspectScoreboardTime());
}
public static void enableGlobalStatsScoreboard(Player player, String skillName, int pageNumber) {
Objective oldObjective = GLOBAL_STATS_SCOREBOARD.getObjective(skillName);
Scoreboard oldScoreboard = player.getScoreboard();
if (oldObjective != null) {
oldObjective.unregister();
}
Objective newObjective = GLOBAL_STATS_SCOREBOARD.registerNewObjective(skillName, "dummy");
newObjective.setDisplayName(ChatColor.GOLD + (skillName.equalsIgnoreCase("all") ? "Power Level" : SkillUtils.getSkillName(SkillType.getSkill(skillName))));
updateGlobalStatsScores(player, newObjective, skillName, pageNumber);
changeScoreboard(player, oldScoreboard, GLOBAL_STATS_SCOREBOARD, Config.getInstance().getMctopScoreboardTime());
}
private static void updatePlayerSkillScores(PlayerProfile profile, SkillType skill, Objective objective) {
Server server = mcMMO.p.getServer();
int currentXP = profile.getSkillXpLevel(skill);
objective.getScore(server.getOfflinePlayer("Level")).setScore(profile.getSkillLevel(skill));
objective.getScore(server.getOfflinePlayer("Current XP")).setScore(currentXP);
objective.getScore(server.getOfflinePlayer("Remaining XP")).setScore(profile.getXpToLevel(skill) - currentXP);
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerStatsScores(McMMOPlayer mcMMOPlayer, Objective objective) {
Player player = mcMMOPlayer.getPlayer();
PlayerProfile profile = mcMMOPlayer.getProfile();
Server server = mcMMO.p.getServer();
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) {
continue;
}
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(profile.getSkillLevel(skill));
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(mcMMOPlayer.getPowerLevel());
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerRankScores(Player player, Objective objective) {
String playerName = player.getName();
Server server = mcMMO.p.getServer();
Integer rank;
Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName);
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) {
continue;
}
rank = skills.get(skill.name());
if (rank != null) {
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(rank);
}
}
rank = skills.get("ALL");
if (rank != null) {
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Overall")).setScore(rank);
}
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerRankOthersScores(String targetName, Objective objective) {
Server server = mcMMO.p.getServer();
Integer rank;
Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(targetName) : FlatfileDatabaseManager.getPlayerRanks(targetName);
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill()) {
continue;
}
rank = skills.get(skill.name());
if (rank != null) {
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(rank);
}
}
rank = skills.get("ALL");
if (rank != null) {
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Overall")).setScore(rank);
}
objective.setDisplayName(PLAYER_RANK_HEADER + ": " + targetName);
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerInspectOnlineScores(McMMOPlayer mcMMOTarget, Objective objective) {
Player target = mcMMOTarget.getPlayer();
PlayerProfile profile = mcMMOTarget.getProfile();
Server server = mcMMO.p.getServer();
int powerLevel = 0;
int skillLevel;
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(target, skill)) {
continue;
}
skillLevel = profile.getSkillLevel(skill);
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(skillLevel);
powerLevel += skillLevel;
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(powerLevel);
objective.setDisplayName(PLAYER_INSPECT_HEADER + target.getName());
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerInspectOfflineScores(PlayerProfile targetProfile, Objective objective) {
Server server = mcMMO.p.getServer();
int powerLevel = 0;
int skillLevel;
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill()) {
continue;
}
skillLevel = targetProfile.getSkillLevel(skill);
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(skillLevel);
powerLevel += skillLevel;
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(powerLevel);
objective.setDisplayName(PLAYER_INSPECT_HEADER + targetProfile.getPlayerName());
}
private static void updateGlobalStatsScores(Player player, Objective objective, String skillName, int pageNumber) {
int position = (pageNumber * 15) - 14;
String startPosition = ((position < 10) ? "0" : "") + String.valueOf(position);
String endPosition = String.valueOf(position + 14);
Server server = mcMMO.p.getServer();
if (Config.getInstance().getUseMySQL()) {
String tablePrefix = Config.getInstance().getMySQLTablePrefix();
String query = (skillName.equalsIgnoreCase("all") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : skillName);
final Collection<ArrayList<String>> userStats = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((pageNumber * 15) - 15) + ",15").values();
for (ArrayList<String> stat : userStats) {
String playerName = stat.get(1);
playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName;
if (playerName.length() > 16) {
playerName = playerName.substring(0, 16);
}
objective.getScore(server.getOfflinePlayer(playerName)).setScore(Integer.valueOf(stat.get(0)));
}
}
else {
for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skillName, pageNumber, 15)) {
String playerName = stat.name;
playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName;
if (playerName.length() > 16) {
playerName = playerName.substring(0, 16);
}
objective.getScore(server.getOfflinePlayer(playerName)).setScore(stat.statVal);
}
}
objective.setDisplayName(objective.getDisplayName() + " (" + startPosition + " - " + endPosition + ")");
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void changeScoreboard(Player player, Scoreboard oldScoreboard, Scoreboard newScoreboard, int displayTime) {
if (oldScoreboard != newScoreboard) {
String playerName = player.getName();
player.setScoreboard(newScoreboard);
enablePowerLevelDisplay(player);
if (displayTime != -1 && !SCOREBOARD_TASKS.contains(playerName)) {
new ScoreboardChangeTask(player, oldScoreboard).runTaskLater(mcMMO.p, displayTime * 20);
SCOREBOARD_TASKS.add(playerName);
}
}
}
public static void clearPendingTask(String playerName) {
SCOREBOARD_TASKS.remove(playerName);
}
}

View File

@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.skills;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Animals;
@@ -18,19 +17,15 @@ import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
@@ -43,6 +38,7 @@ import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.MobHealthbarUtils;
import com.gmail.nossr50.util.ModUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
@@ -249,12 +245,13 @@ public final class CombatUtils {
event.setDamage(archeryManager.dazeCheck((Player) target, event.getDamage()));
}
if (archeryManager.canTrackArrows()) {
if (!damager.hasMetadata(mcMMO.infiniteArrowKey) && archeryManager.canTrackArrows()) {
archeryManager.trackArrows(target);
}
archeryManager.distanceXpBonus(target);
startGainXp(mcMMOPlayer, target, SkillType.ARCHERY);
archeryManager.distanceXpBonus(target, damager);
startGainXp(mcMMOPlayer, target, SkillType.ARCHERY, damager.getMetadata(mcMMO.bowForceKey).get(0).asDouble());
}
break;
@@ -288,40 +285,33 @@ public final class CombatUtils {
swordsManager.counterAttackChecks((LivingEntity) damager, event.getDamage());
}
}
if (damager.getType() == EntityType.ARROW) {
LivingEntity shooter = ((Arrow) damager).getShooter();
if (shooter instanceof Player || !SkillType.UNARMED.getPVEEnabled()) {
return;
}
UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
if (unarmedManager.canDeflect()) {
event.setCancelled(unarmedManager.deflectCheck());
if (event.isCancelled()) {
return;
}
}
}
}
else if (attacker instanceof Player) {
Player player = (Player) attacker;
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
if (Permissions.mobHealthDisplay(player) && profile.getMobHealthbarType() != MobHealthbarType.DISABLED) {
String oldName = target.getCustomName();
boolean oldNameVisible = target.isCustomNameVisible();
String newName = createHealthDisplay(profile, target, event.getDamage());
target.setCustomName(newName);
target.setCustomNameVisible(true);
int displayTime = Config.getInstance().getMobHealthbarTime();
if (displayTime != -1) {
if (oldName == null) {
oldName = "";
}
boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName));
if (updateName) {
target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, oldName));
target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, oldNameVisible));
}
else if (!target.hasMetadata(mcMMO.customNameKey)) {
target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, ""));
target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, false));
}
new MobHealthDisplayUpdaterTask(target).runTaskLater(mcMMO.p, displayTime * 20); // Clear health display after 3 seconds
}
if (Misc.isNPCEntity(player)) {
return;
}
MobHealthbarUtils.handleMobHealthbars(player, target, event.getDamage());
}
}
@@ -435,6 +425,10 @@ public final class CombatUtils {
}
}
public static void startGainXp(McMMOPlayer mcMMOPlayer, LivingEntity target, SkillType skillType) {
startGainXp(mcMMOPlayer, target, skillType, 1.0);
}
/**
* Start the task that gives combat XP.
*
@@ -442,7 +436,7 @@ public final class CombatUtils {
* @param target The defending entity
* @param skillType The skill being used
*/
public static void startGainXp(McMMOPlayer mcMMOPlayer, LivingEntity target, SkillType skillType) {
public static void startGainXp(McMMOPlayer mcMMOPlayer, LivingEntity target, SkillType skillType, double multiplier) {
double baseXP = 0;
if (target instanceof Player) {
@@ -452,11 +446,11 @@ public final class CombatUtils {
Player defender = (Player) target;
if (System.currentTimeMillis() >= UserManager.getPlayer(defender).getRespawnATS() + 5) {
if (defender.isOnline() && System.currentTimeMillis() >= UserManager.getPlayer(defender).getRespawnATS() + 5) {
baseXP = 20 * Config.getInstance().getPlayerVersusPlayerXP();
}
}
else if (!target.hasMetadata(mcMMO.entityMetadataKey)) {
else {
if (target instanceof Animals) {
if (ModUtils.isCustomEntity(target)) {
baseXP = ModUtils.getCustomEntity(target).getXpMultiplier();
@@ -516,11 +510,17 @@ public final class CombatUtils {
}
break;
}
if (target.hasMetadata(mcMMO.entityMetadataKey)) {
baseXP *= Config.getInstance().getSpawnedMobXpMultiplier();
}
}
baseXP *= 10;
}
baseXP *= multiplier;
if (baseXP != 0) {
new AwardCombatXpTask(mcMMOPlayer, skillType, baseXP, target).runTaskLater(mcMMO.p, 0);
}
@@ -622,67 +622,4 @@ public final class CombatUtils {
return process;
}
private static String createHealthDisplay(PlayerProfile profile, LivingEntity entity, int damage) {
int maxHealth = entity.getMaxHealth();
int currentHealth = Math.max(entity.getHealth() - damage, 0);
double healthPercentage = (currentHealth / (double) maxHealth) * 100.0D;
int fullDisplay = 0;
ChatColor color = ChatColor.BLACK;
String symbol = "";
switch (profile.getMobHealthbarType()) {
case HEARTS:
fullDisplay = Math.min(maxHealth / 2, 10);
color = ChatColor.DARK_RED;
symbol = "";
break;
case BAR:
fullDisplay = 10;
if (healthPercentage >= 85) {
color = ChatColor.DARK_GREEN;
}
else if (healthPercentage >= 70) {
color = ChatColor.GREEN;
}
else if (healthPercentage >= 55) {
color = ChatColor.GOLD;
}
else if (healthPercentage >= 40) {
color = ChatColor.YELLOW;
}
else if (healthPercentage >= 25) {
color = ChatColor.RED;
}
else if (healthPercentage >= 0) {
color = ChatColor.DARK_RED;
}
symbol = "";
break;
default:
return null;
}
int coloredDisplay = (int) (fullDisplay * (healthPercentage / 100.0D));
int grayDisplay = fullDisplay - coloredDisplay;
String healthbar = color + "";
for (int i = 0; i < coloredDisplay; i++) {
healthbar += symbol;
}
healthbar += ChatColor.GRAY;
for (int i = 0; i < grayDisplay; i++) {
healthbar += symbol;
}
return healthbar;
}
}

Some files were not shown because too many files have changed in this diff Show More