1
0
mirror of https://github.com/mcMMO-Dev/mcMMO.git synced 2026-02-19 02:12:58 +01:00

Compare commits

..

120 Commits

Author SHA1 Message Date
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
GJ
2c87ce06eb Weekly beta releases are back! 2013-04-11 23:54:10 -04:00
GJ
875091a1ce Added ability to configure drops from Shake in treasures.yml 2013-04-11 21:40:09 -04:00
GJ
5ad7716137 Don't need to store that. 2013-04-11 10:24:22 -04:00
GJ
8c97399cec This is important. 2013-04-11 10:02:08 -04:00
GJ
27e0a9d3b6 Fixed experience commands affecting all skills. Fixes #951 2013-04-11 09:55:39 -04:00
GJ
07f9b287e7 Move exceptions to their own package.
This will break plugins that directly catch these exceptions.
2013-04-10 20:21:55 -04:00
GJ
fbee4f1b37 Remove debug messages. 2013-04-10 19:41:55 -04:00
GJ
26542f3d6e Because otherwise you can't fish at low levels. 2013-04-10 19:32:26 -04:00
GJ
14630fe956 Nerfin' it. 2013-04-10 18:44:11 -04:00
GJ
30f5c761d9 Because some plugins do stupid things. 2013-04-10 17:04:32 -04:00
GJ
365abaaa8f Reverse the order to avoid NPE 2013-04-10 14:04:46 -04:00
GJ
f4681a282c Better handling of picking up items with unarmed. 2013-04-10 13:20:44 -04:00
TfT_02
8a14d9ac26 Update the changelog 2013-04-10 17:19:34 +02:00
TfT_02
0ab1986202 Set a seperate cooldowns between getting hurt and teleportations
Closes #880
2013-04-10 17:19:14 +02:00
TfT_02
e11dc680de Add configurable warmup and cooldown timers for party teleportation
Closes #348
2013-04-10 17:18:06 +02:00
TfT_02
71249334c3 Change the ChimaeraWing timestamp into a general teleportation timestamp 2013-04-10 17:15:48 +02:00
NuclearW
fa41dbce16 Regex used mean look, could not escape! 2013-04-10 00:00:57 -04:00
GJ
4246e6c900 Use char codes instead of symbols, just to be safe. 2013-04-09 23:41:02 -04:00
GJ
1b421a24b0 Remove the drop. 2013-04-09 21:44:27 -04:00
GJ
9cc9eead52 Unbreak the API 2013-04-09 21:09:47 -04:00
GJ
8b21aea9c7 Check Fisherman's Diet permission when checking for display headers. 2013-04-09 20:53:55 -04:00
GJ
4f87cb6446 Added "Master Angler" ability to Fishing.
This ability increases the chance that a fish will bite the line while
fishing.
2013-04-09 20:53:54 -04:00
GJ
7525de1a72 ExperienceAPI methods will now throw InvalidSkillException if the skill
name passed in is invalid
2013-04-09 20:52:58 -04:00
GJ
78d2fa7520 Only care if it was unarmed. 2013-04-09 16:52:41 -04:00
GJ
7fe8122499 Avoid picking up items to the hotbar while using unarmed. Fixes #939 2013-04-09 16:52:38 -04:00
GJ
532c2e7450 Remove unused import 2013-04-09 16:52:35 -04:00
GJ
b391a53c6b Make our commands support tab-complete. 2013-04-08 17:34:23 -04:00
GJ
f3c6346b95 Clear mob health display if it gets stuck. Fixes #933 2013-04-08 00:34:54 -04:00
GJ
dd8984314f Validate here instead. 2013-04-08 00:26:12 -04:00
GJ
b82c3f41d3 Remove metadata, validation checks. 2013-04-08 00:24:38 -04:00
GJ
7d6eb65776 No need to reset. 2013-04-08 00:11:09 -04:00
GJ
dc0800e7e1 Even better regex. 2013-04-08 00:07:07 -04:00
GJ
c151366952 Better regex for this. 2013-04-07 23:58:53 -04:00
GJ
212137ec3e Fix issues with mob healthbars being used in death messages. Fixes #934 2013-04-07 23:22:59 -04:00
GJ
31f36935d3 Avoid NPE when using experience commands on offline players. 2013-04-07 09:01:31 -04:00
TfT_02
a14fc3e3c9 Fixed broken /party chat command
Closes #931
2013-04-06 12:20:20 +02:00
GJ
158b3c43f8 Fixed wolves from Call of the Wild only having 8 health. 2013-04-05 16:17:59 -04:00
GJ
e31c1e33d9 Don't handle removing the name if the entity is dead. 2013-04-05 16:15:24 -04:00
GJ
25dfa6d34d Better way to get the HUD type. 2013-04-04 23:15:37 -04:00
GJ
431429a29c Broken config files are bad. 2013-04-04 23:03:54 -04:00
GJ
d4c8cc28a1 Use new hasConflictingEnchant method. 2013-04-04 22:26:48 -04:00
GJ
ce08405c00 Use new NetherWartState values. 2013-04-04 22:24:02 -04:00
GJ
da29185b7d Added health display for mobs during combat.
During combat, players will now see a healthbar appear over the head of
hostile mobs when they are damaged. This healthbar will have two display
options - HEARTS and BAR - which can be changed via the /mobhealth
command.

New Permissions:
mcmmo.mobhealthdisplay - Allows viewing of mob health display
mcmmo.commands.mobhealth - Allows access to the /mobhealth command

New Config Options (config.yml):
Mob_Healthbar.Display_Type - the default health display type
Mob_Healthbar.Display_Time - the amount of time to show health display
2013-04-04 22:11:11 -04:00
TfT_02
87feb8c250 Added new API method to McMMOPlayerLevelUpEvent to set levels gained
Closes #352
2013-04-04 23:00:21 +02:00
TfT_02
12797893df Update the changelog 2013-04-04 22:50:32 +02:00
TfT_02
6d47e43ba9 Display partial names when trying to use the ptp command 2013-04-04 22:50:22 +02:00
TfT_02
f6b1643378 Minor formatting, added a missing white space 2013-04-04 22:21:13 +02:00
TfT_02
f1c16df63b Added new permission node for party teleportation.
`mcmmo.commands.ptp.send`
This permission node will be check before sending a teleport request
(or teleporting the sender if no request is required), this allows
admins to grant certain groups of users permissions to accept incoming
party teleport request without being able to send ptp requests
themselves.

Closes #927
2013-04-04 22:20:19 +02:00
TfT_02
c16e5231f4 Changed Chimaera Wing's recipe result to use the ingredient Material 2013-04-04 21:35:09 +02:00
GJ
2365c253dd Back to active development. 2013-04-04 10:23:06 -04:00
119 changed files with 4800 additions and 2411 deletions

View File

@@ -6,6 +6,38 @@ Key:
= Fix
! Change
- Removal
Version 1.4.06-dev
+ 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)
= 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.
! 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.
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.05</version>
<version>1.4.06-beta2</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<issueManagement>
@@ -177,4 +177,8 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<ciManagement>
<system>Jenkins</system>
<url>ci.mcmmo.org</url>
</ciManagement>
</project>

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

@@ -4,6 +4,8 @@ import java.util.Set;
import org.bukkit.entity.Player;
import com.gmail.nossr50.api.exceptions.InvalidPlayerException;
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
@@ -21,9 +23,17 @@ public final class ExperienceAPI {
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addRawXP(Player player, String skillType, int XP) {
UserManager.getPlayer(player).applyXpGain(SkillType.getSkill(skillType), XP);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).applyXpGain(skill, XP);
}
/**
@@ -35,10 +45,17 @@ public final class ExperienceAPI {
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addRawXPOffline(String playerName, String skillType, int XP) {
addOfflineXP(playerName, skillType, XP);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
addOfflineXP(playerName, skill, XP);
}
/**
@@ -49,9 +66,17 @@ public final class ExperienceAPI {
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addMultipliedXP(Player player, String skillType, int XP) {
UserManager.getPlayer(player).applyXpGain(SkillType.getSkill(skillType), (int) (XP * Config.getInstance().getExperienceGainsGlobalMultiplier()));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).applyXpGain(skill, (int) (XP * Config.getInstance().getExperienceGainsGlobalMultiplier()));
}
/**
@@ -63,10 +88,17 @@ public final class ExperienceAPI {
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addMultipliedXPOffline(String playerName, String skillType, int XP) {
addOfflineXP(playerName, skillType, (int) (XP * Config.getInstance().getExperienceGainsGlobalMultiplier()));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
addOfflineXP(playerName, skill, (int) (XP * Config.getInstance().getExperienceGainsGlobalMultiplier()));
}
/**
@@ -77,10 +109,16 @@ public final class ExperienceAPI {
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addModifiedXP(Player player, String skillType, int XP) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier()));
}
@@ -93,10 +131,17 @@ public final class ExperienceAPI {
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addModifiedXPOffline(String playerName, String skillType, int XP) {
addOfflineXP(playerName, skillType, (int) (XP / SkillType.getSkill(skillType).getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier()));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
addOfflineXP(playerName, skill, (int) (XP / skill.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier()));
}
/**
@@ -107,9 +152,17 @@ public final class ExperienceAPI {
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addXP(Player player, String skillType, int XP) {
UserManager.getPlayer(player).beginXpGain(SkillType.getSkill(skillType), XP);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).beginXpGain(skill, XP);
}
/**
@@ -120,9 +173,17 @@ public final class ExperienceAPI {
* @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
*/
public static int getXP(Player player, String skillType) {
return UserManager.getPlayer(player).getProfile().getSkillXpLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getSkillXpLevel(skill);
}
/**
@@ -133,10 +194,61 @@ public final class ExperienceAPI {
* @param playerName 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 InvalidPlayerException if the given player does not exist in the database
*/
public static int getOfflineXP(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillXpLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return getOfflineProfile(playerName).getSkillXpLevel(skill);
}
/**
* 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 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
*/
public static float getXPRaw(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getSkillXpLevelRaw(skill);
}
/**
* Get the raw amount of XP an offline player has in a specific skill.
* </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 in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static float getOfflineXPRaw(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return getOfflineProfile(playerName).getSkillXpLevelRaw(skill);
}
/**
@@ -147,9 +259,17 @@ public final class ExperienceAPI {
* @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
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getXPToNextLevel(Player player, String skillType) {
return UserManager.getPlayer(player).getProfile().getXpToLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getXpToLevel(skill);
}
/**
@@ -160,10 +280,18 @@ public final class ExperienceAPI {
* @param playerName 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 InvalidPlayerException if the given player does not exist in the database
*/
public static int getOfflineXPToNextLevel(String playerName, String skillType) {
return getOfflineProfile(playerName).getXpToLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return getOfflineProfile(playerName).getXpToLevel(skill);
}
/**
@@ -174,9 +302,17 @@ public final class ExperienceAPI {
* @param player The player to add levels to
* @param skillType Type of skill to add levels to
* @param levels Number of levels to add
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addLevel(Player player, String skillType, int levels) {
UserManager.getPlayer(player).getProfile().addLevels(SkillType.getSkill(skillType), levels);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).getProfile().addLevels(skill, levels);
}
/**
@@ -188,13 +324,17 @@ public final class ExperienceAPI {
* @param skillType Type of skill to add levels to
* @param levels Number of levels to add
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addLevelOffline(String playerName, String skillType, int levels) {
PlayerProfile profile = getOfflineProfile(playerName);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
if (skill.isChildSkill()) {
Set<SkillType> parentSkills = FamilyTree.getParents(skill);
@@ -218,9 +358,17 @@ public final class ExperienceAPI {
* @param player The player to get the level for
* @param skillType The skill to get the level for
* @return the level of a given skill
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevel(Player player, String skillType) {
return UserManager.getPlayer(player).getProfile().getSkillLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getSkillLevel(skill);
}
/**
@@ -231,10 +379,18 @@ public final class ExperienceAPI {
* @param playerName The player to get the level for
* @param skillType The skill to get the level for
* @return the level of a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static int getLevelOffline(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillLevel(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return getOfflineProfile(playerName).getSkillLevel(skill);
}
/**
@@ -256,6 +412,7 @@ public final class ExperienceAPI {
*
* @param playerName The player to get the power level for
* @return the power level of the player
*
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static int getPowerLevelOffline(String playerName) {
@@ -280,9 +437,17 @@ public final class ExperienceAPI {
*
* @param skillType The skill to get the level cap for
* @return the level cap of a given skill
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevelCap(String skillType) {
return Config.getInstance().getLevelCap(SkillType.getSkill(skillType));
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return Config.getInstance().getLevelCap(skill);
}
/**
@@ -290,7 +455,7 @@ public final class ExperienceAPI {
* </br>
* This function is designed for API usage.
*
* @return the power level cap of a given skill
* @return the overall power level cap
*/
public static int getPowerLevelCap() {
return Config.getInstance().getPowerLevelCap();
@@ -304,9 +469,17 @@ public final class ExperienceAPI {
* @param player The player to set the level of
* @param skillType The skill to set the level for
* @param skillLevel The value to set the level to
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void setLevel(Player player, String skillType, int skillLevel) {
UserManager.getPlayer(player).getProfile().modifySkill(SkillType.getSkill(skillType), skillLevel);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).getProfile().modifySkill(skill, skillLevel);
}
/**
@@ -318,10 +491,17 @@ public final class ExperienceAPI {
* @param skillType The skill to set the level for
* @param skillLevel The value to set the level to
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void setLevelOffline(String playerName, String skillType, int skillLevel) {
getOfflineProfile(playerName).modifySkill(SkillType.getSkill(skillType), skillLevel);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
getOfflineProfile(playerName).modifySkill(skill, skillLevel);
}
/**
@@ -332,9 +512,17 @@ public final class ExperienceAPI {
* @param player The player to set the XP of
* @param skillType The skill to set the XP for
* @param newValue The value to set the XP to
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void setXP(Player player, String skillType, int newValue) {
UserManager.getPlayer(player).getProfile().setSkillXpLevel(SkillType.getSkill(skillType), newValue);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).getProfile().setSkillXpLevel(skill, newValue);
}
/**
@@ -346,10 +534,17 @@ public final class ExperienceAPI {
* @param skillType The skill to set the XP for
* @param newValue The value to set the XP to
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void setXPOffline(String playerName, String skillType, int newValue) {
getOfflineProfile(playerName).setSkillXpLevel(SkillType.getSkill(skillType), newValue);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
getOfflineProfile(playerName).setSkillXpLevel(skill, newValue);
}
/**
@@ -360,9 +555,17 @@ public final class ExperienceAPI {
* @param player The player to change the XP of
* @param skillType The skill to change the XP for
* @param xp The amount of XP to remove
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static void removeXP(Player player, String skillType, int xp) {
UserManager.getPlayer(player).getProfile().removeXp(SkillType.getSkill(skillType), xp);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
UserManager.getPlayer(player).getProfile().removeXp(skill, xp);
}
/**
@@ -374,10 +577,17 @@ public final class ExperienceAPI {
* @param skillType The skill to change the XP for
* @param xp The amount of XP to remove
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void removeXPOffline(String playerName, String skillType, int xp) {
getOfflineProfile(playerName).removeXp(SkillType.getSkill(skillType), xp);
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
getOfflineProfile(playerName).removeXp(skill, xp);
}
/**
@@ -387,11 +597,9 @@ public final class ExperienceAPI {
* @param skillType The skill to check
* @param XP The amount of XP to award.
*/
private static void addOfflineXP(String playerName, String skillType, int XP) {
private static void addOfflineXP(String playerName, SkillType skill, int XP) {
PlayerProfile profile = getOfflineProfile(playerName);
SkillType skill = SkillType.getSkill(skillType);
if (skill.isChildSkill()) {
Set<SkillType> parentSkills = FamilyTree.getParents(skill);

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

@@ -1,4 +1,4 @@
package com.gmail.nossr50.api;
package com.gmail.nossr50.api.exceptions;
public class InvalidPlayerException extends RuntimeException {
private static final long serialVersionUID = 907213002618581385L;

View File

@@ -0,0 +1,9 @@
package com.gmail.nossr50.api.exceptions;
public class InvalidSkillException extends RuntimeException {
private static final long serialVersionUID = 942705284195791157L;
public InvalidSkillException() {
super("That is not a valid skill.");
}
}

View File

@@ -1,74 +1,29 @@
package com.gmail.nossr50.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
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;
public class McabilityCommand implements CommandExecutor {
private McMMOPlayer mcMMOPlayer;
private Player player;
public class McabilityCommand extends ToggleCommand {
@Override
protected boolean hasOtherPermission(CommandSender sender) {
return Permissions.mcabilityOthers(sender);
}
@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.mcability(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
toggleAbilityUse();
return true;
case 1:
if (!Permissions.mcabilityOthers(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(args[0]);
if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
return true;
}
player = mcMMOPlayer.getPlayer();
if (CommandUtils.isOffline(sender, player)) {
return true;
}
toggleAbilityUse();
sender.sendMessage("Ability use has been toggled for " + player.getName()); // TODO: Localize
return true;
default:
return false;
}
protected boolean hasSelfPermission(CommandSender sender) {
return Permissions.mcability(sender);
}
private void toggleAbilityUse() {
if (mcMMOPlayer.getAbilityUse()) {
player.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
}
else {
player.sendMessage(LocaleLoader.getString("Commands.Ability.On"));
}
@Override
protected void applyCommandAction() {
player.sendMessage(LocaleLoader.getString("Commands.Ability." + (mcMMOPlayer.getAbilityUse() ? "Off" : "On")));
mcMMOPlayer.toggleAbilityUse();
}
@Override
protected void sendSuccessMessage(CommandSender sender) {
sender.sendMessage("Ability use has been toggled for " + player.getName()); // TODO: Localize
}
}

View File

@@ -1,74 +1,29 @@
package com.gmail.nossr50.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
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;
public class McgodCommand implements CommandExecutor {
private McMMOPlayer mcMMOPlayer;
private Player player;
public class McgodCommand extends ToggleCommand {
@Override
protected boolean hasOtherPermission(CommandSender sender) {
return Permissions.mcgodOthers(sender);
}
@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.mcgod(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
toggleGodMode();
return true;
case 1:
if (!Permissions.mcgodOthers(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(args[0]);
if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
return true;
}
player = mcMMOPlayer.getPlayer();
if (CommandUtils.isOffline(sender, player)) {
return true;
}
toggleGodMode();
sender.sendMessage("God mode has been toggled for " + player.getName()); // TODO: Localize
return true;
default:
return false;
}
protected boolean hasSelfPermission(CommandSender sender) {
return Permissions.mcgod(sender);
}
private void toggleGodMode() {
if (mcMMOPlayer.getGodMode()) {
player.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
}
else {
player.sendMessage(LocaleLoader.getString("Commands.GodMode.Enabled"));
}
@Override
protected void applyCommandAction() {
player.sendMessage(LocaleLoader.getString("Commands.GodMode." + (mcMMOPlayer.getGodMode() ? "Disabled" : "Enabled")));
mcMMOPlayer.toggleGodMode();
}
@Override
protected void sendSuccessMessage(CommandSender sender) {
sender.sendMessage("God mode has been toggled for " + player.getName()); // TODO: Localize
}
}

View File

@@ -1,27 +1,25 @@
package com.gmail.nossr50.commands;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.player.UserManager;
public class McnotifyCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public class McnotifyCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
case 0:
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
if (mcMMOPlayer.useChatNotifications()) {
sender.sendMessage(LocaleLoader.getString("Commands.Notifications.Off"));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.Notifications.On"));
}
sender.sendMessage(LocaleLoader.getString("Commands.Notifications." + (mcMMOPlayer.useChatNotifications() ? "Off" : "On")));
mcMMOPlayer.toggleChatNotifications();
return true;
@@ -29,4 +27,9 @@ public class McnotifyCommand implements CommandExecutor {
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return ImmutableList.of();
}
}

View File

@@ -1,74 +1,33 @@
package com.gmail.nossr50.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
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;
public class McrefreshCommand implements CommandExecutor {
private McMMOPlayer mcMMOPlayer;
private Player player;
public class McrefreshCommand extends ToggleCommand {
@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.mcrefresh(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
refreshPlayer();
return true;
case 1:
if (!Permissions.mcrefreshOthers(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(args[0]);
if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
return true;
}
Player player = mcMMOPlayer.getPlayer();
if (CommandUtils.isOffline(sender, player)) {
return true;
}
refreshPlayer();
sender.sendMessage(LocaleLoader.getString("Commands.mcrefresh.Success", player.getName()));
return true;
default:
return false;
}
protected boolean hasOtherPermission(CommandSender sender) {
return Permissions.mcrefreshOthers(sender);
}
private void refreshPlayer() {
@Override
protected boolean hasSelfPermission(CommandSender sender) {
return Permissions.mcrefresh(sender);
}
@Override
protected void applyCommandAction() {
mcMMOPlayer.setRecentlyHurt(0);
mcMMOPlayer.getProfile().resetCooldowns();
mcMMOPlayer.resetToolPrepMode();
mcMMOPlayer.resetAbilityMode();
player.setCanPickupItems(true);
player = mcMMOPlayer.getPlayer();
player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
}
@Override
protected void sendSuccessMessage(CommandSender sender) {
sender.sendMessage(LocaleLoader.getString("Commands.mcrefresh.Success", player.getName()));
}
}

View File

@@ -0,0 +1,68 @@
package com.gmail.nossr50.commands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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.MobHealthbarType;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.google.common.collect.ImmutableList;
public class MobhealthCommand implements TabExecutor {
private static final List<String> MOB_HEALTHBAR_TYPES;
static {
ArrayList<String> types = new ArrayList<String>();
for (MobHealthbarType type : MobHealthbarType.values()) {
types.add(type.toString());
}
Collections.sort(types);
MOB_HEALTHBAR_TYPES = ImmutableList.copyOf(types);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (CommandUtils.noConsoleUsage(sender)) {
return true;
}
switch (args.length) {
case 1:
PlayerProfile playerProfile = UserManager.getPlayer(sender.getName()).getProfile();
try {
MobHealthbarType type = MobHealthbarType.valueOf(args[0].toUpperCase().trim());
playerProfile.setMobHealthbarType(type);
sender.sendMessage("Display type changed to: " + type); //TODO: Localize
return true;
}
catch (IllegalArgumentException ex) {
sender.sendMessage("Invalid type!"); //TODO: Localize
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], MOB_HEALTHBAR_TYPES, new ArrayList<String>(MOB_HEALTHBAR_TYPES.size()));
default:
return ImmutableList.of();
}
}
}

View File

@@ -0,0 +1,84 @@
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.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.google.common.collect.ImmutableList;
public abstract class ToggleCommand implements TabExecutor {
protected McMMOPlayer mcMMOPlayer;
protected Player player;
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
case 0:
if (CommandUtils.noConsoleUsage(sender)) {
return true;
}
if (!hasSelfPermission(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
applyCommandAction();
return true;
case 1:
if (!hasOtherPermission(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
mcMMOPlayer = UserManager.getPlayer(args[0]);
if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
return true;
}
player = mcMMOPlayer.getPlayer();
if (CommandUtils.isOffline(sender, player)) {
return true;
}
applyCommandAction();
sendSuccessMessage(sender);
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();
}
}
protected abstract boolean hasOtherPermission(CommandSender sender);
protected abstract boolean hasSelfPermission(CommandSender sender);
protected abstract void applyCommandAction();
protected abstract void sendSuccessMessage(CommandSender sender);
}

View File

@@ -1,16 +1,23 @@
package com.gmail.nossr50.commands;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
public class XprateCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public class XprateCommand implements TabExecutor {
private double originalRate;
public XprateCommand() {
@@ -75,4 +82,20 @@ public class XprateCommand implements CommandExecutor {
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
if (StringUtils.isInt(args[0])) {
return ImmutableList.of();
}
return StringUtil.copyPartialMatches(args[0], CommandUtils.RESET_OPTIONS, new ArrayList<String>(CommandUtils.RESET_OPTIONS.size()));
case 2:
return StringUtil.copyPartialMatches(args[1], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
default:
return ImmutableList.of();
}
}
}

View File

@@ -1,8 +1,12 @@
package com.gmail.nossr50.commands.chat;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.chat.ChatMode;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -10,7 +14,9 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
public abstract class ChatCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public abstract class ChatCommand implements TabExecutor {
protected ChatMode chatMode;
private McMMOPlayer mcMMOPlayer;
@@ -68,6 +74,16 @@ public abstract class ChatCommand implements CommandExecutor {
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
default:
return ImmutableList.of();
}
}
protected String buildChatMessage(String[] args, int index) {
StringBuilder builder = new StringBuilder();
builder.append(args[index]);

View File

@@ -1,16 +1,19 @@
package com.gmail.nossr50.commands.database;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import java.util.List;
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;
public class McpurgeCommand implements CommandExecutor {
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)) {
@@ -20,19 +23,10 @@ public class McpurgeCommand implements CommandExecutor {
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"));
@@ -42,4 +36,9 @@ public class McpurgeCommand implements CommandExecutor {
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return ImmutableList.of();
}
}

View File

@@ -1,17 +1,24 @@
package com.gmail.nossr50.commands.database;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
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;
public class McremoveCommand implements CommandExecutor {
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)) {
@@ -21,26 +28,15 @@ public class McremoveCommand implements CommandExecutor {
switch (args.length) {
case 1:
/* MySQL */
if (Config.getInstance().getUseMySQL()) {
String tablePrefix = Config.getInstance().getMySQLTablePrefix();
if (UserManager.getPlayer(args[0]) == null && CommandUtils.unloadedProfile(sender, new PlayerProfile(args[0], false))) {
return true;
}
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]));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
}
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]));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
}
sender.sendMessage(args[0] + " could not be removed from the database."); // Pretty sure this should NEVER happen.
}
return true;
@@ -49,4 +45,15 @@ public class McremoveCommand implements CommandExecutor {
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,8 +1,10 @@
package com.gmail.nossr50.commands.database;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
@@ -12,7 +14,9 @@ import com.gmail.nossr50.runnables.database.SQLConversionTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
public class MmoupdateCommand implements CommandExecutor {
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)) {
@@ -20,12 +24,17 @@ public class MmoupdateCommand implements CommandExecutor {
return true;
}
if (!Config.getInstance().getUseMySQL()) {
sender.sendMessage("SQL Mode is not enabled."); // TODO: Localize
return true;
}
switch (args.length) {
case 0:
sender.sendMessage(LocaleLoader.getString("Commands.mmoupdate.Start"));
UserManager.saveAll();
UserManager.clearAll();
convertToMySQL();
new SQLConversionTask().runTaskLaterAsynchronously(mcMMO.p, 1);
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
UserManager.addUser(player);
@@ -39,14 +48,8 @@ public class MmoupdateCommand implements CommandExecutor {
}
}
/**
* Convert FlatFile data to MySQL data.
*/
private void convertToMySQL() {
if (!Config.getInstance().getUseMySQL()) {
return;
}
new SQLConversionTask().runTaskLaterAsynchronously(mcMMO.p, 1);
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return ImmutableList.of();
}
}

View File

@@ -31,6 +31,5 @@ public class AddlevelsCommand extends ExperienceCommand {
@Override
protected void handlePlayerMessageSkill() {
player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, SkillUtils.getSkillName(skill)));
}
}

View File

@@ -1,9 +1,14 @@
package com.gmail.nossr50.commands.experience;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -13,8 +18,9 @@ import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.google.common.collect.ImmutableList;
public abstract class ExperienceCommand implements CommandExecutor {
public abstract class ExperienceCommand implements TabExecutor {
protected McMMOPlayer mcMMOPlayer;
protected Player player;
protected PlayerProfile profile;
@@ -45,6 +51,7 @@ public abstract class ExperienceCommand implements CommandExecutor {
profile = mcMMOPlayer.getProfile();
editValues();
allSkills = false;
return true;
case 3:
@@ -58,7 +65,6 @@ public abstract class ExperienceCommand implements CommandExecutor {
}
mcMMOPlayer = UserManager.getPlayer(args[0]);
player = mcMMOPlayer.getPlayer();
// 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.
if (mcMMOPlayer == null) {
@@ -73,10 +79,12 @@ public abstract class ExperienceCommand implements CommandExecutor {
}
else {
profile = mcMMOPlayer.getProfile();
player = mcMMOPlayer.getPlayer();
editValues();
}
handleSenderMessage(sender, args[0]);
allSkills = false;
return true;
default:
@@ -84,6 +92,19 @@ public abstract class ExperienceCommand implements CommandExecutor {
}
}
@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()));
case 2:
return StringUtil.copyPartialMatches(args[1], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
default:
return ImmutableList.of();
}
}
protected abstract boolean permissionsCheckSelf(CommandSender sender);
protected abstract boolean permissionsCheckOthers(CommandSender sender);
protected abstract void handleCommand(SkillType skill);

View File

@@ -1,15 +1,21 @@
package com.gmail.nossr50.commands.hardcore;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils;
public abstract class HardcoreModeCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public abstract class HardcoreModeCommand implements TabExecutor {
protected CommandSender sender;
protected double newPercent;
protected DecimalFormat percent;
@@ -76,6 +82,20 @@ public abstract class HardcoreModeCommand implements CommandExecutor {
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
if (StringUtils.isDouble(args[0])) {
return ImmutableList.of();
}
return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
default:
return ImmutableList.of();
}
}
protected abstract boolean checkTogglePermissions();
protected abstract boolean checkModifyPermissions();
protected abstract boolean checkEnabled();

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

@@ -1,21 +1,46 @@
package com.gmail.nossr50.commands.party;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
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.commands.chat.PartyChatCommand;
import com.gmail.nossr50.commands.party.teleport.PtpCommand;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
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.google.common.collect.ImmutableList;
public class PartyCommand implements CommandExecutor {
public class PartyCommand implements TabExecutor {
private McMMOPlayer mcMMOPlayer;
private Player player;
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", "misc");
static {
ArrayList<String> subcommands = new ArrayList<String>();
for (PartySubcommandType subcommand : PartySubcommandType.values()) {
subcommands.add(subcommand.toString());
}
Collections.sort(subcommands);
PARTY_SUBCOMMANDS = ImmutableList.copyOf(subcommands);
}
private CommandExecutor partyJoinCommand = new PartyJoinCommand();
private CommandExecutor partyAcceptCommand = new PartyAcceptCommand();
private CommandExecutor partyCreateCommand = new PartyCreateCommand();
@@ -32,7 +57,7 @@ public class PartyCommand implements CommandExecutor {
private CommandExecutor partyInfoCommand = new PartyInfoCommand();
private CommandExecutor partyHelpCommand = new PartyHelpCommand();
private CommandExecutor partyTeleportCommand = mcMMO.p.getCommand("ptp").getExecutor();
private CommandExecutor partyChatCommand = mcMMO.p.getCommand("partychat").getExecutor();
private CommandExecutor partyChatCommand = new PartyChatCommand();
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@@ -134,6 +159,57 @@ public class PartyCommand implements CommandExecutor {
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[0], PARTY_SUBCOMMANDS, new ArrayList<String>(PARTY_SUBCOMMANDS.size()));
case 2:
PartySubcommandType subcommand = PartySubcommandType.getSubcommand(args[0]);
if (subcommand == null) {
return ImmutableList.of();
}
switch (subcommand) {
case JOIN:
case INVITE:
case KICK:
case OWNER:
Set<String> playerNames = UserManager.getPlayers().keySet();
return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<String>(playerNames.size()));
case EXPSHARE:
return StringUtil.copyPartialMatches(args[1], EXPSHARE_COMPLETIONS, new ArrayList<String>(EXPSHARE_COMPLETIONS.size()));
case ITEMSHARE:
return StringUtil.copyPartialMatches(args[1], ITEMSHARE_COMPLETIONS, new ArrayList<String>(ITEMSHARE_COMPLETIONS.size()));
case LOCK:
case CHAT:
return StringUtil.copyPartialMatches(args[1], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
case PASSWORD:
return StringUtil.copyPartialMatches(args[1], CommandUtils.RESET_OPTIONS, new ArrayList<String>(CommandUtils.RESET_OPTIONS.size()));
case TELEPORT:
List<String> matches = StringUtil.copyPartialMatches(args[1], PtpCommand.TELEPORT_SUBCOMMANDS, new ArrayList<String>(PtpCommand.TELEPORT_SUBCOMMANDS.size()));
if (matches.size() == 0) {
playerNames = UserManager.getPlayers().keySet();
return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<String>(playerNames.size()));
}
return matches;
default:
return ImmutableList.of();
}
case 3:
if (PartySubcommandType.getSubcommand(args[0]) == PartySubcommandType.ITEMSHARE && isItemShareCategory(args[1])) {
return StringUtil.copyPartialMatches(args[2], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
}
return ImmutableList.of();
default:
return ImmutableList.of();
}
}
private boolean printUsage() {
player.sendMessage(LocaleLoader.getString("Party.Help.0", "/party join"));
player.sendMessage(LocaleLoader.getString("Party.Help.1", "/party create"));
@@ -150,4 +226,9 @@ public class PartyCommand implements CommandExecutor {
return newArgs;
}
private boolean isItemShareCategory(String category) {
return category.equalsIgnoreCase("loot") || category.equalsIgnoreCase("mining") || category.equalsIgnoreCase("herbalism") || category.equalsIgnoreCase("woodcutting") || category.equalsIgnoreCase("misc");
}
}

View File

@@ -35,7 +35,7 @@ public class PartyExpShareCommand implements CommandExecutor {
handleChangingShareMode(ShareMode.EQUAL);
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "expshare", "[NONE | EQUAL]"));
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "expshare", "<NONE | EQUAL>"));
}
return true;

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;
@@ -21,21 +22,28 @@ public class PartyInfoCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
playerParty = mcMMOPlayer.getParty();
switch (args.length) {
case 0:
case 1:
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
player = mcMMOPlayer.getPlayer();
playerParty = mcMMOPlayer.getParty();
displayPartyHeader();
displayShareModeInfo();
displayMemberInfo();
return true;
displayPartyHeader();
displayShareModeInfo();
displayMemberInfo();
return true;
default:
sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "info"));
return true;
}
}
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

@@ -58,7 +58,7 @@ public class PtpAcceptCommand implements CommandExecutor {
}
}
PtpCommand.handlePartyTeleportEvent(target, player);
PtpCommand.handleTeleportWarmup(target, player);
return true;
}
}

View File

@@ -1,9 +1,16 @@
package com.gmail.nossr50.commands.party.teleport;
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;
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;
@@ -11,14 +18,20 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.party.McMMOPartyTeleportEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.runnables.items.TeleportationWarmup;
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;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.google.common.collect.ImmutableList;
public class PtpCommand implements CommandExecutor {
public class PtpCommand implements TabExecutor {
private static Player target;
private static McMMOPlayer mcMMOTarget;
public static final List<String> TELEPORT_SUBCOMMANDS = ImmutableList.of("toggle", "accept", "acceptany", "acceptall");
private CommandExecutor ptpToggleCommand = new PtpToggleCommand();
private CommandExecutor ptpAcceptAnyCommand = new PtpAcceptAnyCommand();
private CommandExecutor ptpAcceptCommand = new PtpAcceptCommand();
@@ -42,11 +55,11 @@ public class PtpCommand implements CommandExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
Player player = mcMMOPlayer.getPlayer();
int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
int recentlyhurt_cooldown = Config.getInstance().getPTPCommandRecentlyHurtCooldown();
if (((recentlyHurt * Misc.TIME_CONVERSION_FACTOR) + (ptpCooldown * Misc.TIME_CONVERSION_FACTOR)) > System.currentTimeMillis()) {
player.sendMessage(LocaleLoader.getString("Party.Teleport.Hurt", ptpCooldown));
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 true;
}
@@ -54,6 +67,19 @@ public class PtpCommand implements CommandExecutor {
return ptpAcceptCommand.onCommand(sender, command, label, args);
}
if (!Permissions.partyTeleportSend(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
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!
return true;
}
sendTeleportRequest(sender, player, args[0]);
return true;
@@ -62,13 +88,30 @@ public class PtpCommand implements CommandExecutor {
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
List<String> matches = StringUtil.copyPartialMatches(args[0], TELEPORT_SUBCOMMANDS, new ArrayList<String>(TELEPORT_SUBCOMMANDS.size()));
if (matches.size() == 0) {
Set<String> playerNames = UserManager.getPlayers().keySet();
return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
}
return matches;
default:
return ImmutableList.of();
}
}
private void sendTeleportRequest(CommandSender sender, Player player, String targetName) {
if (!canTeleport(sender, player, targetName)) {
return;
}
if (!mcMMOTarget.getPtpConfirmRequired()) {
handlePartyTeleportEvent(player, target);
handleTeleportWarmup(player, target);
return;
}
@@ -89,6 +132,7 @@ public class PtpCommand implements CommandExecutor {
}
target = mcMMOTarget.getPlayer();
targetName = target.getName();
if (player.equals(target)) {
player.sendMessage(LocaleLoader.getString("Party.Teleport.Self"));
@@ -113,7 +157,24 @@ public class PtpCommand implements CommandExecutor {
return true;
}
protected static void handlePartyTeleportEvent(Player teleportingPlayer, Player targetPlayer) {
protected static void handleTeleportWarmup(Player teleportingPlayer, Player targetPlayer) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
mcMMOTarget = UserManager.getPlayer(targetPlayer);
long warmup = Config.getInstance().getPTPCommandWarmup();
mcMMOPlayer.actualizeTeleportCommenceLocation(teleportingPlayer);
if (warmup > 0) {
teleportingPlayer.sendMessage(ChatColor.GRAY + "Commencing teleport in " + ChatColor.GOLD + "(" + warmup + ")" + ChatColor.GRAY + " seconds, please stand still..."); //TODO Locale!
new TeleportationWarmup(mcMMOPlayer, mcMMOTarget).runTaskLater(mcMMO.p, 20 * warmup);
}
else {
handlePartyTeleportEvent(teleportingPlayer, targetPlayer);
}
}
public static void handlePartyTeleportEvent(Player teleportingPlayer, Player targetPlayer) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(teleportingPlayer, targetPlayer, mcMMOPlayer.getParty().getName());

View File

@@ -1,10 +1,16 @@
package com.gmail.nossr50.commands.player;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
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.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;
@@ -12,12 +18,19 @@ 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;
public class InspectCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public class InspectCommand implements TabExecutor {
@Override
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.
@@ -28,6 +41,11 @@ public class InspectCommand implements CommandExecutor {
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"));
@@ -55,6 +73,11 @@ public class InspectCommand implements CommandExecutor {
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);
@@ -68,4 +91,15 @@ public class InspectCommand implements CommandExecutor {
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,23 +1,27 @@
package com.gmail.nossr50.commands.player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
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 CommandExecutor {
public class McrankCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
@@ -31,11 +35,12 @@ public class McrankCommand implements CommandExecutor {
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;
@@ -55,18 +60,18 @@ public class McrankCommand implements CommandExecutor {
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:
@@ -74,39 +79,18 @@ public class McrankCommand implements CommandExecutor {
}
}
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]));
@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();
}
}
private void sqlDisplay(CommandSender sender, String playerName) {
private void display(CommandSender sender, String playerName) {
new McrankCommandAsyncTask(playerName, sender).runTaskAsynchronously(mcMMO.p);
}
}

View File

@@ -1,8 +1,10 @@
package com.gmail.nossr50.commands.player;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.Config;
@@ -10,8 +12,10 @@ 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 CommandExecutor {
public class McstatsCommand implements TabExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (CommandUtils.noConsoleUsage(sender)) {
@@ -23,20 +27,26 @@ public class McstatsCommand implements CommandExecutor {
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;
@@ -45,4 +55,9 @@ public class McstatsCommand implements CommandExecutor {
return false;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return ImmutableList.of();
}
}

View File

@@ -1,36 +1,42 @@
package com.gmail.nossr50.commands.player;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
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;
public class MctopCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public class MctopCommand implements TabExecutor {
private SkillType skill;
@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;
}
@@ -38,7 +44,7 @@ public class MctopCommand implements CommandExecutor {
return true;
}
display(1, skill.toString(), sender, useMySQL, command);
display(1, skill.toString(), sender, command);
return true;
case 2:
@@ -50,7 +56,7 @@ public class MctopCommand implements CommandExecutor {
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:
@@ -58,27 +64,37 @@ public class MctopCommand implements CommandExecutor {
}
}
private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
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, 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"));
@@ -89,21 +105,11 @@ public class MctopCommand implements CommandExecutor {
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

@@ -15,11 +15,13 @@ public class FishingCommand extends SkillCommand {
private String shakeChance;
private String shakeChanceLucky;
private int fishermansDietRank;
private String biteChance;
private boolean canTreasureHunt;
private boolean canMagicHunt;
private boolean canShake;
private boolean canFishermansDiet;
private boolean canMasterAngler;
public FishingCommand() {
super(SkillType.FISHING);
@@ -27,12 +29,14 @@ public class FishingCommand extends SkillCommand {
@Override
protected void dataCalculations() {
boolean isStorming = player.getWorld().hasStorm();
// TREASURE HUNTER
if (canTreasureHunt) {
lootTier = mcMMOPlayer.getFishingManager().getLootTier();
double enchantChance = lootTier * AdvancedConfig.getInstance().getFishingMagicMultiplier();
if (player.getWorld().hasStorm()) {
if (isStorming) {
chanceRaining = LocaleLoader.getString("Fishing.Chance.Raining");
enchantChance *= 1.1D;
}
@@ -53,6 +57,11 @@ public class FishingCommand extends SkillCommand {
if (canFishermansDiet) {
fishermansDietRank = calculateRank(Fishing.fishermansDietMaxLevel, Fishing.fishermansDietRankLevel1);
}
// MASTER ANGLER
if (canMasterAngler) {
biteChance = calculateAbilityDisplayValues(((Math.max((skillValue / 200.0), 1.0)) / (isStorming ? 300 : 500)) * 100.0)[0];
}
}
@Override
@@ -61,11 +70,12 @@ public class FishingCommand extends SkillCommand {
canMagicHunt = Permissions.magicHunter(player);
canShake = Permissions.shake(player);
canFishermansDiet = Permissions.fishermansDiet(player);
canMasterAngler = Permissions.masterAngler(player);
}
@Override
protected boolean effectsHeaderPermissions() {
return canTreasureHunt || canMagicHunt || canShake;
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet;
}
@Override
@@ -87,15 +97,23 @@ public class FishingCommand extends SkillCommand {
if (canFishermansDiet) {
player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Fishing.Effect.6"), LocaleLoader.getString("Fishing.Effect.7")));
}
if (canMasterAngler) {
player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Fishing.Effect.8"), LocaleLoader.getString("Fishing.Effect.9")));
}
}
@Override
protected boolean statsHeaderPermissions() {
return canTreasureHunt || canMagicHunt || canShake;
return canTreasureHunt || canMagicHunt || canShake || canMasterAngler || canFishermansDiet;
}
@Override
protected void statsDisplay() {
if (canMasterAngler) {
player.sendMessage(LocaleLoader.getString("Fishing.Ability.Chance", biteChance));
}
if (canTreasureHunt) {
player.sendMessage(LocaleLoader.getString("Fishing.Ability.Rank", lootTier));
}

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

@@ -1,14 +1,17 @@
package com.gmail.nossr50.commands.skills;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Set;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
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;
@@ -18,10 +21,13 @@ 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;
public abstract class SkillCommand implements CommandExecutor {
import com.google.common.collect.ImmutableList;
public abstract class SkillCommand implements TabExecutor {
protected SkillType skill;
protected String skillName;
@@ -67,7 +73,14 @@ public abstract class SkillCommand implements CommandExecutor {
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")));
@@ -102,6 +115,16 @@ public abstract class SkillCommand implements CommandExecutor {
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return ImmutableList.of("?");
default:
return ImmutableList.of();
}
}
protected int calculateRank(int maxLevel, int rankChangeLevel) {
return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
}

View File

@@ -1,12 +1,41 @@
package com.gmail.nossr50.commands.spout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.datatypes.spout.huds.HudType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.google.common.collect.ImmutableList;
public class MchudCommand extends SpoutCommand {
private static final List<String> HUD_TYPES;
static {
ArrayList<String> types = new ArrayList<String>();
for (HudType type : HudType.values()) {
types.add(type.toString());
}
Collections.sort(types);
HUD_TYPES = ImmutableList.copyOf(types);
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[0], HUD_TYPES, new ArrayList<String>(HUD_TYPES.size()));
default:
return ImmutableList.of();
}
}
@Override
protected boolean noArguments(Command command, CommandSender sender, String[] args) {
return false;
@@ -14,16 +43,15 @@ public class MchudCommand extends SpoutCommand {
@Override
protected boolean oneArgument(Command command, CommandSender sender, String[] args) {
for (HudType hudType : HudType.values()) {
if (hudType.toString().equalsIgnoreCase(args[0])) {
playerProfile.setHudType(hudType);
spoutHud.initializeXpBar();
spoutHud.updateXpBar();
return true;
}
try {
playerProfile.setHudType(HudType.valueOf(args[0].toUpperCase().trim()));
spoutHud.initializeXpBar();
spoutHud.updateXpBar();
return true;
}
catch (IllegalArgumentException ex) {
sender.sendMessage(LocaleLoader.getString("Commands.mchud.Invalid"));
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.mchud.Invalid"));
return true;
}
}

View File

@@ -1,8 +1,8 @@
package com.gmail.nossr50.commands.spout;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.spout.SpoutConfig;
@@ -12,7 +12,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
public abstract class SpoutCommand implements CommandExecutor {
public abstract class SpoutCommand implements TabExecutor {
protected PlayerProfile playerProfile;
protected McMMOHud spoutHud;

View File

@@ -1,15 +1,36 @@
package com.gmail.nossr50.commands.spout;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.google.common.collect.ImmutableList;
public class XplockCommand extends SpoutCommand {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
List<String> matches = StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
if (matches.size() == 0) {
return StringUtil.copyPartialMatches(args[0], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
}
return matches;
default:
return ImmutableList.of();
}
}
@Override
protected boolean noArguments(Command command, CommandSender sender, String[] args) {
if (spoutHud.getXpBarLocked()) {

View File

@@ -6,6 +6,7 @@ import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.util.StringUtils;
@@ -48,6 +49,34 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getPartyDisplayNames() { return config.getBoolean("Commands.p.Use_Display_Names", true); }
public boolean getAdminDisplayNames() { return config.getBoolean("Commands.a.Use_Display_Names", true); }
/* Mob Healthbar */
public MobHealthbarType getMobHealthbarDefault() {
try {
return MobHealthbarType.valueOf(config.getString("Mob_Healthbar.Display_Type", "HEARTS").toUpperCase().trim());
}
catch (IllegalArgumentException ex) {
return MobHealthbarType.HEARTS;
}
}
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.Mctop.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); }
/* 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); }
@@ -108,6 +137,7 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getChimaeraPreventUseUnderground() { return config.getBoolean("Items.Chimaera_Wing.Prevent_Use_Underground", true); }
public int getChimaeraCooldown() { return config.getInt("Items.Chimaera_Wing.Cooldown", 240); }
public int getChimaeraWarmup() { return config.getInt("Items.Chimaera_Wing.Warmup", 5); }
public int getChimaeraRecentlyHurtCooldown() { return config.getInt("Items.Chimaera_Wing.RecentlyHurt_Cooldown", 60); }
/* Particles */
public boolean getAbilityActivationEffectEnabled() { return config.getBoolean("Particles.Ability_Activation", true); }
@@ -129,7 +159,9 @@ public class Config extends AutoUpdateConfigLoader {
public double getPartyShareRange() { return config.getDouble("Party.Sharing.Range", 75.0); }
/* Party Teleport Settings */
public int getPTPCommandCooldown() { return config.getInt("Commands.ptp.Cooldown", 30); }
public int getPTPCommandCooldown() { return config.getInt("Commands.ptp.Cooldown", 120); }
public int getPTPCommandWarmup() { return config.getInt("Commands.ptp.Warmup", 5); }
public int getPTPCommandRecentlyHurtCooldown() { return config.getInt("Commands.ptp.RecentlyHurt_Cooldown", 60); }
public int getPTPCommandTimeout() { return config.getInt("Commands.ptp.Request_Timeout", 300); }
public boolean getPTPCommandConfirmRequired() { return config.getBoolean("Commands.ptp.Confirm_Required", true); }
public boolean getPTPCommandWorldPermissions() { return config.getBoolean("Commands.ptp.World_Based_Permissions", false); }
@@ -192,6 +224,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); }

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

@@ -6,11 +6,9 @@ import com.gmail.nossr50.datatypes.spout.huds.HudType;
public class SpoutConfig extends ConfigLoader {
private static SpoutConfig instance;
public HudType defaultHudType;
private SpoutConfig() {
super("spout.yml");
loadKeys();
}
public static SpoutConfig getInstance() {
@@ -24,17 +22,14 @@ public class SpoutConfig extends ConfigLoader {
@Override
protected void loadKeys() {
// Setup default HUD
String temp = config.getString("Spout.HUD.Default", "STANDARD");
}
for (HudType hudType : HudType.values()) {
if (hudType.toString().equalsIgnoreCase(temp)) {
defaultHudType = hudType;
break;
}
public HudType getDefaultHudType() {
try {
return HudType.valueOf(config.getString("Spout.HUD.Default", "STANDARD").toUpperCase().trim());
}
if (defaultHudType == null) {
defaultHudType = HudType.STANDARD;
catch (IllegalArgumentException ex) {
return HudType.STANDARD;
}
}

View File

@@ -9,13 +9,17 @@ import java.util.Set;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionType;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.treasure.ExcavationTreasure;
import com.gmail.nossr50.datatypes.treasure.FishingTreasure;
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
import com.gmail.nossr50.datatypes.treasure.ShakeTreasure;
import com.gmail.nossr50.datatypes.treasure.Treasure;
public class TreasureConfig extends ConfigLoader {
@@ -33,6 +37,27 @@ public class TreasureConfig extends ConfigLoader {
public List<HylianTreasure> hylianFromFlowers = new ArrayList<HylianTreasure>();
public List<HylianTreasure> hylianFromPots = new ArrayList<HylianTreasure>();
public List<ShakeTreasure> shakeFromBlaze = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromCaveSpider = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSpider = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromChicken = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromCow = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromCreeper = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromEnderman = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromGhast = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromIronGolem = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromMagmaCube = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromMushroomCow = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromPig = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromPigZombie = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSheep = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSkeleton = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSlime = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSnowman = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromSquid = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromWitch = new ArrayList<ShakeTreasure>();
public List<ShakeTreasure> shakeFromZombie = new ArrayList<ShakeTreasure>();
public List<FishingTreasure> fishingRewards = new ArrayList<FishingTreasure>();
private TreasureConfig() {
@@ -128,15 +153,32 @@ public class TreasureConfig extends ConfigLoader {
reason.add("Invalid Drop_Level: " + dropLevel);
}
/*
* Potions
*/
ItemStack item = null;
if (config.contains("Treasures." + treasureName + ".Potion_Type")) {
String potionType = config.getString("Treasures." + treasureName + ".Potion_Type");
try {
item = new Potion(PotionType.valueOf(potionType.toUpperCase())).toItemStack(amount);
}
catch (IllegalArgumentException ex) {
reason.add("Invalid Potion_Type: " + potionType);
}
}
else {
item = (new MaterialData(id, (byte) data)).toItemStack(amount);
}
/*
* Drops From & Max Level
*/
ItemStack item = (new MaterialData(id, (byte) data)).toItemStack(amount);
if (config.getBoolean("Treasures." + treasureName + ".Drops_From.Fishing", false)) {
if (config.getConfigurationSection("Treasures." + treasureName + ".Drops_From").getKeys(false).size() != 1) {
reason.add("Fishing drops cannot also be excavation drops");
reason.add("This can only be a fishing drop.");
}
if (!config.contains("Treasures." + treasureName + ".Max_Level")) {
@@ -150,6 +192,30 @@ public class TreasureConfig extends ConfigLoader {
treasures.put(treasureName, fTreasure);
}
}
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.");
}
if (!config.contains("Treasures." + treasureName + ".Mob")) {
reason.add("Missing Mob");
}
String mobType = config.getString("Treasures." + treasureName + ".Mob");
EntityType mob = null;
try {
mob = EntityType.valueOf(mobType.toUpperCase().trim());
}
catch (IllegalArgumentException ex){
reason.add("Invalid Mob: " + mobType);
}
if (noErrorsInTreasure(reason)) {
ShakeTreasure sTreasure = new ShakeTreasure(item, xp, dropChance, dropLevel, mob);
treasures.put(treasureName, sTreasure);
}
}
else {
ExcavationTreasure eTreasure = new ExcavationTreasure(item, xp, dropChance, dropLevel);
HylianTreasure hTreasure = new HylianTreasure(item, xp, dropChance, dropLevel);
@@ -195,7 +261,11 @@ public class TreasureConfig extends ConfigLoader {
}
if (config.getBoolean("Treasures." + treasureName + ".Drops_From.Fishing", false)) {
reason.add("Excavation drops cannot also be fishing drops");
reason.add("This cannot also be a fishing drop.");
}
if (config.getBoolean("Treasures." + treasureName + ".Drops_From.Shake", false)) {
reason.add("This cannot also be a shake drop.");
}
if (noErrorsInTreasure(reason) && hTreasure.getDropsFrom() == (byte) 0x0) {
@@ -210,6 +280,7 @@ public class TreasureConfig extends ConfigLoader {
List<String> excavationTreasures = config.getStringList("Excavation.Treasure");
List<String> fishingTreasures = config.getStringList("Fishing.Treasure");
List<String> hylianTreasures = config.getStringList("Hylian_Luck.Treasure");
List<String> shakeTreasures = config.getStringList("Shake.Treasure");
for (Entry<String, Treasure> nextEntry : treasures.entrySet()) {
String treasureKey = nextEntry.getKey();
@@ -222,6 +293,97 @@ public class TreasureConfig extends ConfigLoader {
fishingRewards.add((FishingTreasure) treasure);
}
else if (treasure instanceof ShakeTreasure) {
if (shakeTreasures == null || !shakeTreasures.contains(treasureKey)) {
continue;
}
ShakeTreasure e = (ShakeTreasure) treasure;
switch (e.getMob()) {
case BLAZE:
shakeFromBlaze.add(e);
break;
case CAVE_SPIDER:
shakeFromCaveSpider.add(e);
break;
case CHICKEN:
shakeFromChicken.add(e);
break;
case COW:
shakeFromCow.add(e);
break;
case CREEPER:
shakeFromCreeper.add(e);
break;
case ENDERMAN:
shakeFromEnderman.add(e);
break;
case GHAST:
shakeFromGhast.add(e);
break;
case IRON_GOLEM:
shakeFromIronGolem.add(e);
break;
case MAGMA_CUBE:
shakeFromMagmaCube.add(e);
break;
case MUSHROOM_COW:
shakeFromMushroomCow.add(e);
break;
case PIG:
shakeFromPig.add(e);
break;
case PIG_ZOMBIE:
shakeFromPigZombie.add(e);
break;
case SHEEP:
shakeFromSheep.add(e);
break;
case SKELETON:
shakeFromSkeleton.add(e);
break;
case SLIME:
shakeFromSlime.add(e);
break;
case SPIDER:
shakeFromSpider.add(e);
break;
case SNOWMAN:
shakeFromSnowman.add(e);
break;
case SQUID:
shakeFromSquid.add(e);
break;
case WITCH:
shakeFromWitch.add(e);
break;
case ZOMBIE:
shakeFromZombie.add(e);
break;
default:
break;
}
}
else if (treasure instanceof HylianTreasure) {
if (hylianTreasures == null || !hylianTreasures.contains(treasureKey)) {
continue;

View File

@@ -1,643 +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',"
+ "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);
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;
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;
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,628 @@
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`)) 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);
}
/**
* 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);
}
}
}
}
public static boolean removeUserSQL(String playerName) {
return SQLDatabaseManager.update("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.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 " + 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)");
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 " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM (SELECT id FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")) AS p)");
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 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);
}
}
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;
}
}
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

@@ -0,0 +1,7 @@
package com.gmail.nossr50.datatypes;
public enum MobHealthbarType {
HEARTS,
BAR,
DISABLED;
}

View File

@@ -4,5 +4,6 @@ public enum DatabaseUpdateType {
FISHING,
BLAST_MINING,
CASCADE_DELETE,
INDEX;
INDEX,
MOB_HEALTHBARS;
}

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,40 @@
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.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,42 +59,30 @@ 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()) {
if (shareLootDrops) {
shareCategories.add("Loot");
}
if (sharingMiningDrops()) {
if (shareMiningDrops) {
shareCategories.add("Mining");
}
if (sharingHerbalismDrops()) {
if (shareHerbalismDrops) {
shareCategories.add("Herbalism");
}
if (sharingWoodcuttingDrops()) {
if (shareWoodcuttingDrops) {
shareCategories.add("Woodcutting");
}
if (shareMiscDrops) {
shareCategories.add("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

@@ -70,7 +70,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>();
@@ -79,11 +81,12 @@ public class McMMOPlayer {
private Map<ToolType, Boolean> toolMode = new HashMap<ToolType, Boolean>();
private Map<ToolType, Integer> toolATS = new HashMap<ToolType, Integer>();
private int chimaeraWing;
private Location chimaeraWingCommence;
private int recentlyHurt;
private int respawnATS;
private int teleportLastUse;
private Location teleportCommence;
private boolean isUsingUnarmed;
public McMMOPlayer(Player player) {
String playerName = player.getName();
@@ -303,31 +306,31 @@ public class McMMOPlayer {
}
/*
* Chimaera Wing
* Teleportation cooldown & warmup
*/
public int getLastChimaeraTeleport() {
return chimaeraWing;
public int getLastTeleport() {
return teleportLastUse;
}
public void setLastChimaeraTeleport(int value) {
chimaeraWing = value;
public void setLastTeleport(int value) {
teleportLastUse = value;
}
public void actualizeLastChimaeraTeleport() {
chimaeraWing = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
public void actualizeLastTeleport() {
teleportLastUse = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
}
public Location getChimaeraCommenceLocation() {
return chimaeraWingCommence;
public Location getTeleportCommenceLocation() {
return teleportCommence;
}
public void setChimaeraCommenceLocation(Location location) {
chimaeraWingCommence = location;
public void setTeleportCommenceLocation(Location location) {
teleportCommence = location;
}
public void actualizeChimaeraCommenceLocation(Player player) {
setChimaeraCommenceLocation(player.getLocation());
public void actualizeTeleportCommenceLocation(Player player) {
setTeleportCommenceLocation(player.getLocation());
}
/*
@@ -368,6 +371,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
*/
@@ -419,7 +458,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;
}
@@ -450,7 +489,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);
@@ -462,7 +501,7 @@ 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);
@@ -483,7 +522,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();
@@ -491,6 +530,7 @@ public class McMMOPlayer {
spoutHud.setLastGained(skillType);
}
isUsingUnarmed = skillType == SkillType.UNARMED;
SkillUtils.xpCheckSkill(skillType, player, profile);
}
@@ -642,6 +682,10 @@ public class McMMOPlayer {
partyChatMode = !partyChatMode;
}
public boolean isUsingUnarmed() {
return isUsingUnarmed;
}
/**
* Modifies an experience gain using skill modifiers, global rate and perks
*
@@ -649,12 +693,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

@@ -1,5 +1,9 @@
package com.gmail.nossr50.datatypes.skills;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.Color;
import com.gmail.nossr50.mcMMO;
@@ -20,6 +24,8 @@ import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.google.common.collect.ImmutableList;
public enum SkillType {
ACROBATICS(AcrobaticsManager.class, Color.WHITE),
@@ -41,6 +47,19 @@ public enum SkillType {
private AbilityType ability;
private ToolType tool;
public static final List<String> SKILL_NAMES;
static {
ArrayList<String> names = new ArrayList<String>();
for (SkillType skill : values()) {
names.add(SkillUtils.getSkillName(skill));
}
Collections.sort(names);
SKILL_NAMES = ImmutableList.copyOf(names);
}
private SkillType(Class<? extends SkillManager> managerClass, Color runescapeColor) {
this.managerClass = managerClass;
this.runescapeColor = runescapeColor;

View File

@@ -0,0 +1,21 @@
package com.gmail.nossr50.datatypes.treasure;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
public class ShakeTreasure extends Treasure {
private EntityType mob;
public ShakeTreasure(ItemStack drop, int xp, double dropChance, int dropLevel, EntityType mob) {
super(drop, xp, dropChance, dropLevel);
this.mob = mob;
}
public EntityType getMob() {
return mob;
}
public void setMob(EntityType mob) {
this.mob = mob;
}
}

View File

@@ -17,6 +17,14 @@ public class McMMOPlayerLevelUpEvent extends McMMOPlayerExperienceEvent {
public McMMOPlayerLevelUpEvent(Player player, SkillType skill, int levelsGained) {
super(player, skill);
this.setLevelsGained(levelsGained);
}
/**
* @param levelsGained
* @return Set the number of levels gained in this event
*/
public void setLevelsGained(int levelsGained) {
this.levelsGained = levelsGained;
}

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

@@ -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

@@ -68,12 +68,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);
}
}

View File

@@ -163,26 +163,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

@@ -1,7 +1,9 @@
package com.gmail.nossr50.listeners;
import org.bukkit.ChatColor;
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;
@@ -40,12 +42,15 @@ 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;
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;
@@ -58,32 +63,41 @@ public class PlayerListener implements Listener {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerDeathLowest(PlayerDeathEvent event) {
String deathMessage = event.getDeathMessage();
if (deathMessage == null) {
return;
}
event.setDeathMessage(MobHealthbarUtils.fixDeathMessage(deathMessage, event.getEntity()));
}
/**
* Monitor PlayerDeath events.
*
* @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);
}
/**
@@ -92,7 +106,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)) {
@@ -118,16 +132,18 @@ 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();
}
/**
@@ -136,16 +152,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());
}
/**
@@ -164,6 +175,12 @@ public class PlayerListener implements Listener {
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager();
switch (event.getState()) {
case FISHING:
if (fishingManager.canMasterAngler()) {
fishingManager.masterAngler(event.getHook());
}
break;
case CAUGHT_FISH:
fishingManager.handleFishing((Item) event.getCaught());
@@ -174,7 +191,6 @@ public class PlayerListener implements Listener {
case CAUGHT_ENTITY:
Entity entity = event.getCaught();
if (fishingManager.canShake(entity)) {
fishingManager.shakeCheck((LivingEntity) entity);
}
@@ -193,16 +209,32 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
Player player = event.getPlayer();
Item item = event.getItem();
if (Misc.isNPCEntity(player)) {
return;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
Item drop = event.getItem();
ItemStack dropStack = drop.getItemStack();
if (mcMMOPlayer.inParty() && ItemUtils.isShareable(item.getItemStack())) {
ShareHandler.handleItemShare(event, mcMMOPlayer);
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)) || 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;
}
}
}
@@ -219,10 +251,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
}
@@ -236,10 +264,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);
}
@@ -248,7 +272,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"));
}
@@ -278,31 +302,40 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerInteractLowest(PlayerInteractEvent event) {
Player player = event.getPlayer();
Block block = event.getClickedBlock();
ItemStack heldItem = player.getItemInHand();
if (Misc.isNPCEntity(player) || player.getGameMode() == GameMode.CREATIVE) {
return;
}
Block block = event.getClickedBlock();
ItemStack heldItem = player.getItemInHand();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
MiningManager miningManager = mcMMOPlayer.getMiningManager();
MiningManager miningManager = UserManager.getPlayer(player).getMiningManager();
switch (event.getAction()) {
case RIGHT_CLICK_BLOCK:
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 = UserManager.getPlayer(player).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 = UserManager.getPlayer(player).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()) {
@@ -316,6 +349,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 = UserManager.getPlayer(player).getRepairManager();
// Cancel repairing an enchanted item
if (repairManager.checkConfirmation(blockID, false) && Config.getInstance().getRepairConfirmRequired()) {
UserManager.getPlayer(player).setLastAnvilUse(Repair.repairAnvilId, 0);
player.sendMessage(ChatColor.RED + "Repair cancelled!"); //TODO Locale!
}
}
/* SALVAGE CHECKS */
else if (blockID == Repair.salvageAnvilId && Permissions.salvage(player) && Repair.isSalvageable(heldItem)) {
RepairManager repairManager = UserManager.getPlayer(player).getRepairManager();
// Cancel salvaging an enchanted item
if (repairManager.checkConfirmation(blockID, false) && Config.getInstance().getRepairConfirmRequired()) {
UserManager.getPlayer(player).setLastAnvilUse(Repair.salvageAnvilId, 0);
player.sendMessage(ChatColor.RED + "Salvage cancelled!"); //TODO Locale!
}
}
break;
case RIGHT_CLICK_AIR:
/* BLAST MINING CHECK */
if (miningManager.canDetonate()) {
@@ -441,7 +500,6 @@ public class PlayerListener implements Listener {
return;
}
boolean isAsync = event.isAsynchronous();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (mcMMOPlayer.getPartyChatMode()) {
@@ -452,11 +510,11 @@ public class PlayerListener implements Listener {
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

@@ -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,7 +23,6 @@ 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;
@@ -39,7 +38,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,41 +54,48 @@ import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.spout.SpoutUtils;
public class mcMMO extends JavaPlugin {
/* Listeners */
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 WorldListener worldListener = new WorldListener(this);
private final SelfListener selfListener = new SelfListener();
private final WorldListener worldListener = new WorldListener();
public static mcMMO p;
/* Managers */
private static ChunkManager placeStore;
private static RepairableManager repairableManager;
private static DatabaseManager databaseManager;
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
public static boolean spoutEnabled;
public static boolean combatTagEnabled;
// XP Event Check
private boolean xpEventEnabled = false;
private boolean xpEventEnabled;
// 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 static FixedMetadataValue metadataValue;
@@ -108,30 +113,20 @@ public class mcMMO extends JavaPlugin {
setupSpout();
loadConfigFiles();
if (!Config.getInstance().getUseMySQL()) {
UserManager.loadUsers();
}
combatTagEnabled = getServer().getPluginManager().isPluginEnabled("CombatTag");
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();
@@ -196,7 +191,7 @@ public class mcMMO extends JavaPlugin {
}
}
getLogger().info("Was disabled."); // How informative!
debug("Was disabled."); // How informative!
}
public static String getMainDirectory() {
@@ -215,6 +210,10 @@ public class mcMMO extends JavaPlugin {
return modDirectory;
}
public boolean isUpdateAvailable() {
return updateAvailable;
}
public boolean isXPEventEnabled() {
return xpEventEnabled;
}
@@ -231,6 +230,18 @@ 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;
}
/**
* Setup the various storage file paths
*/
@@ -355,6 +366,7 @@ public class mcMMO extends JavaPlugin {
CommandRegistrationManager.registerHardcoreCommand();
CommandRegistrationManager.registerVampirismCommand();
CommandRegistrationManager.registerMcnotifyCommand();
CommandRegistrationManager.registerMobhealthCommand();
// Spout commands
CommandRegistrationManager.registerXplockCommand();
@@ -373,9 +385,6 @@ public class mcMMO extends JavaPlugin {
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);

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

@@ -4,16 +4,16 @@ import java.util.List;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerPickupItemEvent;
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 {
@@ -22,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;
}
}
};
@@ -48,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()) {
@@ -67,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;
}
@@ -91,9 +94,8 @@ public final class ShareHandler {
* @param mcMMOPlayer Player who picked up the item
* @return True if the item has been shared
*/
public static boolean handleItemShare(PlayerPickupItemEvent event, McMMOPlayer mcMMOPlayer) {
Item item = event.getItem();
ItemStack itemStack = item.getItemStack();
public static boolean handleItemShare(Item drop, McMMOPlayer mcMMOPlayer) {
ItemStack itemStack = drop.getItemStack();
Party party = mcMMOPlayer.getParty();
Player player = mcMMOPlayer.getPlayer();
Player winningPlayer = null;
@@ -101,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;
}
@@ -126,8 +121,7 @@ public final class ShareHandler {
nearMembers.add(player);
partySize = nearMembers.size();
event.setCancelled(true);
item.remove();
drop.remove();
int itemWeight = ItemWeightConfig.getInstance().getItemWeight(itemStack.getType());
for (int i = 0; i < itemStack.getAmount(); i++) {
@@ -163,6 +157,7 @@ public final class ShareHandler {
winningPlayer.updateInventory();
}
return true;
case RANDOM:
nearMembers = PartyManager.getNearMembers(player, party, Config.getInstance().getPartyShareRange());
@@ -172,8 +167,7 @@ public final class ShareHandler {
partySize = nearMembers.size() + 1;
event.setCancelled(true);
item.remove();
drop.remove();
for (int i = 0; i < itemStack.getAmount(); i++) {
int randomMember = Misc.getRandom().nextInt(partySize);
@@ -192,8 +186,8 @@ public final class ShareHandler {
winningPlayer.updateInventory();
}
return true;
case NONE:
// Fallthrough
default:
return false;
}

View File

@@ -0,0 +1,30 @@
package com.gmail.nossr50.runnables;
import org.bukkit.entity.LivingEntity;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
public class MobHealthDisplayUpdaterTask extends BukkitRunnable {
private LivingEntity target;
private String oldName;
private boolean oldNameVisible;
public MobHealthDisplayUpdaterTask(LivingEntity target) {
if (target.isValid()) {
this.target = target;
this.oldName = target.getMetadata(mcMMO.customNameKey).get(0).asString();
this.oldNameVisible = target.getMetadata(mcMMO.customVisibleKey).get(0).asBoolean();
}
}
@Override
public void run() {
if (target.isValid()) {
target.setCustomNameVisible(oldNameVisible);
target.setCustomName(oldName);
target.removeMetadata(mcMMO.customNameKey, mcMMO.p);
target.removeMetadata(mcMMO.customVisibleKey, mcMMO.p);
}
}
}

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.SQLDatabaseManager;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
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

@@ -28,12 +28,12 @@ public class ChimaeraWingWarmup extends BukkitRunnable {
private void checkChimaeraWingTeleport() {
Player player = mcMMOPlayer.getPlayer();
Location previousLocation = mcMMOPlayer.getChimaeraCommenceLocation();
Location previousLocation = mcMMOPlayer.getTeleportCommenceLocation();
Location newLocation = mcMMOPlayer.getPlayer().getLocation();
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
ItemStack inHand = player.getItemInHand();
mcMMOPlayer.setChimaeraCommenceLocation(null);
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!
@@ -45,8 +45,10 @@ public class ChimaeraWingWarmup extends BukkitRunnable {
return;
}
if (!SkillUtils.cooldownOver(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, 60, player)) {
player.sendMessage(LocaleLoader.getString("Item.Injured.Wait", SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, 60, player)));
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;
}

View File

@@ -0,0 +1,60 @@
package com.gmail.nossr50.runnables.items;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.commands.party.teleport.PtpCommand;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.SkillUtils;
public class TeleportationWarmup extends BukkitRunnable {
private static Player teleportingPlayer;
private McMMOPlayer mcMMOPlayer;
private static Player targetPlayer;
private McMMOPlayer mcMMOTarget;
public TeleportationWarmup(McMMOPlayer mcMMOPlayer, McMMOPlayer mcMMOTarget) {
this.mcMMOPlayer = mcMMOPlayer;
this.mcMMOTarget = mcMMOTarget;
}
@Override
public void run() {
checkPartyTeleport();
}
private void checkPartyTeleport() {
teleportingPlayer = mcMMOPlayer.getPlayer();
targetPlayer = mcMMOTarget.getPlayer();
Location previousLocation = mcMMOPlayer.getTeleportCommenceLocation();
Location newLocation = mcMMOPlayer.getPlayer().getLocation();
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
mcMMOPlayer.setTeleportCommenceLocation(null);
if (!PartyManager.inSameParty(teleportingPlayer, targetPlayer)) {
teleportingPlayer.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetPlayer.getName()));
return;
}
if (newLocation.distanceSquared(previousLocation) > 1.0) {
teleportingPlayer.sendMessage(ChatColor.DARK_RED + "Teleportation canceled!"); //TODO Locale!
return;
}
int recentlyhurt_cooldown = Config.getInstance().getPTPCommandRecentlyHurtCooldown();
if (!SkillUtils.cooldownOver(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, teleportingPlayer)) {
teleportingPlayer.sendMessage(LocaleLoader.getString("Item.Injured.Wait", SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, recentlyhurt_cooldown, teleportingPlayer)));
return;
}
PtpCommand.handlePartyTeleportEvent(teleportingPlayer, targetPlayer);
}
}

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,23 @@
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() {
player.setScoreboard(oldScoreboard);
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,59 @@
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.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;
}
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

@@ -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

@@ -1,16 +1,13 @@
package com.gmail.nossr50.skills.fishing;
import java.util.Map;
import java.util.Map.Entry;
import java.util.List;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionType;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.treasure.TreasureConfig;
import com.gmail.nossr50.datatypes.treasure.ShakeTreasure;
import com.gmail.nossr50.util.Misc;
public final class Fishing {
@@ -66,115 +63,70 @@ public final class Fishing {
* @param target Targeted entity
* @param possibleDrops List of ItemStack that can be dropped
*/
protected static void findPossibleDrops(LivingEntity target, Map<ItemStack, Integer> possibleDrops) {
protected static List<ShakeTreasure> findPossibleDrops(LivingEntity target) {
switch (target.getType()) {
case BLAZE:
possibleDrops.put(new ItemStack(Material.BLAZE_ROD), 100);
break;
return TreasureConfig.getInstance().shakeFromBlaze;
case CAVE_SPIDER:
case SPIDER:
possibleDrops.put(new ItemStack(Material.SPIDER_EYE), 50);
possibleDrops.put(new ItemStack(Material.STRING), 50);
break;
return TreasureConfig.getInstance().shakeFromCaveSpider;
case CHICKEN:
possibleDrops.put(new ItemStack(Material.FEATHER), 34);
possibleDrops.put(new ItemStack(Material.RAW_CHICKEN), 33);
possibleDrops.put(new ItemStack(Material.EGG), 33);
break;
return TreasureConfig.getInstance().shakeFromChicken;
case COW:
possibleDrops.put(new ItemStack(Material.MILK_BUCKET), 2);
possibleDrops.put(new ItemStack(Material.LEATHER), 49);
possibleDrops.put(new ItemStack(Material.RAW_BEEF), 49);
break;
return TreasureConfig.getInstance().shakeFromCow;
case CREEPER:
possibleDrops.put(new ItemStack(Material.SKULL_ITEM, 1, (short) 4), 1);
possibleDrops.put(new ItemStack(Material.SULPHUR), 99);
break;
return TreasureConfig.getInstance().shakeFromCreeper;
case ENDERMAN:
possibleDrops.put(new ItemStack(Material.ENDER_PEARL), 100);
break;
return TreasureConfig.getInstance().shakeFromEnderman;
case GHAST:
possibleDrops.put(new ItemStack(Material.SULPHUR), 50);
possibleDrops.put(new ItemStack(Material.GHAST_TEAR), 50);
break;
return TreasureConfig.getInstance().shakeFromGhast;
case IRON_GOLEM:
possibleDrops.put(new ItemStack(Material.PUMPKIN), 3);
possibleDrops.put(new ItemStack(Material.IRON_INGOT), 12);
possibleDrops.put(new ItemStack(Material.RED_ROSE), 85);
break;
return TreasureConfig.getInstance().shakeFromIronGolem;
case MAGMA_CUBE:
possibleDrops.put(new ItemStack(Material.MAGMA_CREAM), 100);
break;
return TreasureConfig.getInstance().shakeFromMagmaCube;
case MUSHROOM_COW:
possibleDrops.put(new ItemStack(Material.MILK_BUCKET), 5);
possibleDrops.put(new ItemStack(Material.MUSHROOM_SOUP), 5);
possibleDrops.put(new ItemStack(Material.LEATHER), 30);
possibleDrops.put(new ItemStack(Material.RAW_BEEF), 30);
possibleDrops.put(new ItemStack(Material.RED_MUSHROOM, Misc.getRandom().nextInt(3) + 1), 30);
break;
return TreasureConfig.getInstance().shakeFromMushroomCow;
case PIG:
possibleDrops.put(new ItemStack(Material.PORK), 100);
break;
return TreasureConfig.getInstance().shakeFromPig;
case PIG_ZOMBIE:
possibleDrops.put(new ItemStack(Material.ROTTEN_FLESH), 50);
possibleDrops.put(new ItemStack(Material.GOLD_NUGGET), 50);
break;
return TreasureConfig.getInstance().shakeFromPigZombie;
case SHEEP:
possibleDrops.put(new ItemStack(Material.WOOL, Misc.getRandom().nextInt(6) + 1), 100);
break;
return TreasureConfig.getInstance().shakeFromSheep;
case SKELETON:
possibleDrops.put(new ItemStack(Material.SKULL_ITEM, 1, (short) 0), 2);
possibleDrops.put(new ItemStack(Material.BONE), 49);
possibleDrops.put(new ItemStack(Material.ARROW, Misc.getRandom().nextInt(3) + 1), 49);
break;
return TreasureConfig.getInstance().shakeFromSkeleton;
case SLIME:
possibleDrops.put(new ItemStack(Material.SLIME_BALL), 100);
break;
return TreasureConfig.getInstance().shakeFromSlime;
case SNOWMAN:
possibleDrops.put(new ItemStack(Material.PUMPKIN), 3);
possibleDrops.put(new ItemStack(Material.SNOW_BALL, Misc.getRandom().nextInt(4) + 1), 97);
break;
return TreasureConfig.getInstance().shakeFromSnowman;
case SPIDER:
return TreasureConfig.getInstance().shakeFromSpider;
case SQUID:
possibleDrops.put(new ItemStack(Material.INK_SACK, 1, DyeColor.BLACK.getDyeData()), 100);
break;
return TreasureConfig.getInstance().shakeFromSquid;
case WITCH:
possibleDrops.put(new Potion(PotionType.INSTANT_HEAL).toItemStack(1), 1);
possibleDrops.put(new Potion(PotionType.FIRE_RESISTANCE).toItemStack(1), 1);
possibleDrops.put(new Potion(PotionType.SPEED).toItemStack(1), 1);
possibleDrops.put(new ItemStack(Material.GLASS_BOTTLE), 9);
possibleDrops.put(new ItemStack(Material.GLOWSTONE_DUST), 13);
possibleDrops.put(new ItemStack(Material.SULPHUR), 12);
possibleDrops.put(new ItemStack(Material.REDSTONE), 13);
possibleDrops.put(new ItemStack(Material.SPIDER_EYE), 12);
possibleDrops.put(new ItemStack(Material.STICK), 13);
possibleDrops.put(new ItemStack(Material.SUGAR), 12);
possibleDrops.put(new ItemStack(Material.POTION), 13);
break;
return TreasureConfig.getInstance().shakeFromWitch;
case ZOMBIE:
possibleDrops.put(new ItemStack(Material.SKULL_ITEM, 1, (short) 2), 2);
possibleDrops.put(new ItemStack(Material.ROTTEN_FLESH), 98);
break;
return TreasureConfig.getInstance().shakeFromZombie;
default:
return;
return null;
}
}
@@ -184,15 +136,15 @@ public final class Fishing {
* @param possibleDrops List of ItemStack that can be dropped
* @return Chosen ItemStack
*/
protected static ItemStack chooseDrop(Map<ItemStack, Integer> possibleDrops) {
protected static ItemStack chooseDrop(List<ShakeTreasure> possibleDrops) {
int dropProbability = Misc.getRandom().nextInt(100);
int cumulatedProbability = 0;
double cumulatedProbability = 0;
for (Entry<ItemStack, Integer> entry : possibleDrops.entrySet()) {
cumulatedProbability += entry.getValue();
for (ShakeTreasure treasure : possibleDrops) {
cumulatedProbability += treasure.getDropChance();
if (dropProbability < cumulatedProbability) {
return entry.getKey();
return treasure.getDrop();
}
}

View File

@@ -2,13 +2,12 @@ package com.gmail.nossr50.skills.fishing;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
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;
@@ -23,6 +22,7 @@ import com.gmail.nossr50.config.treasure.TreasureConfig;
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.locale.LocaleLoader;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.fishing.Fishing.Tier;
@@ -41,6 +41,10 @@ public class FishingManager extends SkillManager {
return target instanceof LivingEntity && getSkillLevel() >= AdvancedConfig.getInstance().getShakeUnlockLevel() && Permissions.shake(getPlayer());
}
public boolean canMasterAngler() {
return Permissions.masterAngler(getPlayer());
}
/**
* Gets the loot tier
*
@@ -86,6 +90,10 @@ public class FishingManager extends SkillManager {
return SkillUtils.handleFoodSkills(getPlayer(), skill, eventFoodLevel, Fishing.fishermansDietRankLevel1, Fishing.fishermansDietMaxLevel, rankChange);
}
public void masterAngler(Fish hook) {
hook.setBiteChance(Math.min(hook.getBiteChance() * Math.max((getSkillLevel() / 200.0), 1.0), 1.0));
}
/**
* Process the results from a successful fishing trip
*
@@ -104,7 +112,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"));
@@ -135,11 +143,9 @@ public class FishingManager extends SkillManager {
*/
public void shakeCheck(LivingEntity target) {
if (getShakeProbability() > Misc.getRandom().nextInt(getActivationChance())) {
Map<ItemStack, Integer> possibleDrops = new HashMap<ItemStack, Integer>();
List<ShakeTreasure> possibleDrops = Fishing.findPossibleDrops(target);
Fishing.findPossibleDrops(target, possibleDrops);
if (possibleDrops.isEmpty()) {
if (possibleDrops == null || possibleDrops.isEmpty()) {
return;
}
@@ -263,17 +269,7 @@ public class FishingManager extends SkillManager {
int specificChance = 1;
for (Enchantment possibleEnchantment : possibleEnchantments) {
boolean conflicts = false;
for (Enchantment currentEnchantment : treasureDrop.getEnchantments().keySet()) {
conflicts = currentEnchantment.conflictsWith(possibleEnchantment);
if (conflicts) {
break;
}
}
if (!conflicts && Misc.getRandom().nextInt(specificChance) == 0) {
if (!treasureDrop.getItemMeta().hasConflictingEnchant(possibleEnchantment) && Misc.getRandom().nextInt(specificChance) == 0) {
treasureDrop.addEnchantment(possibleEnchantment, Misc.getRandom().nextInt(possibleEnchantment.getMaxLevel()) + 1);
specificChance++;

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

@@ -5,12 +5,14 @@ import java.util.List;
import org.bukkit.CropState;
import org.bukkit.Material;
import org.bukkit.NetherWartsState;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.material.CocoaPlant;
import org.bukkit.material.CocoaPlant.CocoaPlantSize;
import org.bukkit.material.NetherWarts;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
@@ -116,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;
}
@@ -204,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;
}
@@ -307,20 +309,22 @@ public class HerbalismManager extends SkillManager {
return true;
case NETHER_WARTS:
NetherWarts warts = (NetherWarts) blockState.getData();
if (greenTerra) {
blockState.setRawData((byte) 2);
warts.setState(NetherWartsState.STAGE_TWO);
}
else {
int greenThumbStage = getGreenThumbStage();
if (greenThumbStage > 2) {
blockState.setRawData((byte) 2);
warts.setState(NetherWartsState.STAGE_TWO);
}
else if (greenThumbStage == 2) {
blockState.setRawData((byte) 1);
warts.setState(NetherWartsState.STAGE_ONE);
}
else {
blockState.setRawData((byte) 0);
warts.setState(NetherWartsState.SEEDED);
}
}

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
}

View File

@@ -3,6 +3,7 @@ package com.gmail.nossr50.skills.repair;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
@@ -14,6 +15,7 @@ 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,6 +25,7 @@ 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;
public class RepairManager extends SkillManager {
@@ -65,7 +68,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 +196,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(ChatColor.GREEN + "Right-click again to confirm " + ChatColor.GOLD + "Repair" + ChatColor.GREEN + ". Left-click to cancel."); //TODO Locale
}
if (anvilId == Repair.salvageAnvilId) {
player.sendMessage(ChatColor.GREEN + "Right-click again to confirm " + ChatColor.GOLD + "Salvage" + ChatColor.GREEN + ". Left-click to cancel."); //TODO Locale
}
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

@@ -194,9 +194,15 @@ public class TamingManager extends SkillManager {
((Ocelot) entity).setCatType(Ocelot.Type.getType(1 + Misc.getRandom().nextInt(3)));
}
else {
entity.setMaxHealth(20);
entity.setHealth(entity.getMaxHealth());
}
if (Permissions.renamePets(player)) {
entity.setCustomName(player.getName() + "\'s " + StringUtils.getPrettyEntityTypeString(entity.getType())); //TODO Localize, perhaps in a different language it makes more sense to switch this around
entity.setCustomNameVisible(true);
}
player.setItemInHand(new ItemStack(heldItem.getType(), heldItemAmount - summonAmount));
player.sendMessage(LocaleLoader.getString("Taming.Summon.Complete"));
}

View File

@@ -1,5 +1,11 @@
package com.gmail.nossr50.skills.unarmed;
import java.util.Iterator;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
@@ -19,4 +25,61 @@ public class Unarmed {
public static boolean blockCrackerSmoothBrick = Config.getInstance().getUnarmedBlockCrackerSmoothbrickToCracked();
public static double berserkDamageModifier = 1.5;
public static boolean handleItemPickup(PlayerInventory inventory, Item drop) {
ItemStack dropStack = drop.getItemStack();
int firstEmpty = inventory.firstEmpty();
if (inventory.containsAtLeast(dropStack, 1)) {
int dropAmount = dropStack.getAmount();
int nextSlot = 0;
for (Iterator<ItemStack> iterator = inventory.iterator(); iterator.hasNext();) {
ItemStack itemstack = iterator.next();
if (dropStack.isSimilar(itemstack)) {
int itemAmount = itemstack.getAmount();
int itemMax = itemstack.getMaxStackSize();
ItemStack addStack = itemstack.clone();
if (dropAmount + itemAmount <= itemMax) {
drop.remove();
addStack.setAmount(dropAmount + itemAmount);
inventory.setItem(nextSlot, addStack);
return true;
}
addStack.setAmount(itemMax);
dropAmount = dropAmount + itemAmount - itemMax;
inventory.setItem(nextSlot, addStack);
}
if (dropAmount == 0) {
drop.remove();
return true;
}
nextSlot++;
}
}
if (firstEmpty == inventory.getHeldItemSlot()) {
int nextSlot = firstEmpty + 1;
for (Iterator<ItemStack> iterator = inventory.iterator(nextSlot); iterator.hasNext();) {
ItemStack itemstack = iterator.next();
if (itemstack == null) {
drop.remove();
inventory.setItem(nextSlot, dropStack);
return true;
}
nextSlot++;
}
}
return false;
}
}

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

@@ -1,9 +1,11 @@
package com.gmail.nossr50.util;
import org.bukkit.CropState;
import org.bukkit.NetherWartsState;
import org.bukkit.block.BlockState;
import org.bukkit.material.CocoaPlant;
import org.bukkit.material.CocoaPlant.CocoaPlantSize;
import org.bukkit.material.NetherWarts;
import com.gmail.nossr50.config.Config;
@@ -62,7 +64,7 @@ public final class BlockUtils {
return blockState.getRawData() == CropState.RIPE.getData();
case NETHER_WARTS:
return blockState.getRawData() == (byte) 0x3;
return ((NetherWarts) blockState.getData()).getState() == NetherWartsState.RIPE;
case COCOA:
return ((CocoaPlant) blockState.getData()).getSize() == CocoaPlantSize.LARGE;
@@ -194,7 +196,7 @@ public final class BlockUtils {
return blockState.getRawData() == CropState.RIPE.getData();
case NETHER_WARTS:
return blockState.getRawData() == (byte) 0x3;
return ((NetherWarts) blockState.getData()).getState() == NetherWartsState.RIPE;
case COCOA:
return ((CocoaPlant) blockState.getData()).getSize() == CocoaPlantSize.LARGE;

View File

@@ -41,55 +41,60 @@ public final class ChimaeraWing {
return;
}
if (!Permissions.chimaeraWing(player)) {
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
return;
}
mcMMOPlayer = UserManager.getPlayer(player);
location = player.getLocation();
int amount = inHand.getAmount();
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
long lastChimaeraWing = mcMMOPlayer.getLastChimaeraTeleport();
long lastTeleport = mcMMOPlayer.getLastTeleport();
if (Permissions.chimaeraWing(player) && ItemUtils.isChimaeraWing(inHand)) {
if (mcMMOPlayer.getChimaeraCommenceLocation() != null) {
if (mcMMOPlayer.getTeleportCommenceLocation() != null) {
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;
}
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", "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;
}
}
if (Config.getInstance().getChimaeraCooldown() > 0 && !SkillUtils.cooldownOver(lastChimaeraWing * 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(lastChimaeraWing * Misc.TIME_CONVERSION_FACTOR, Config.getInstance().getChimaeraCooldown(), player) + ")"); //TODO Locale!
return;
}
mcMMOPlayer.actualizeTeleportCommenceLocation(player);
if (!SkillUtils.cooldownOver(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, 60, player)) {
player.sendMessage(LocaleLoader.getString("Item.Injured.Wait", SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, 60, player)));
return;
}
long warmup = Config.getInstance().getChimaeraWarmup();
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.actualizeLastChimaeraTeleport();
return;
}
}
mcMMOPlayer.actualizeChimaeraCommenceLocation(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(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();
}
}
@@ -110,7 +115,7 @@ public final class ChimaeraWing {
}
player.setItemInHand(new ItemStack(getChimaeraWing(player.getItemInHand().getAmount() - Config.getInstance().getChimaeraUseCost())));
UserManager.getPlayer(player).actualizeLastChimaeraTeleport();
UserManager.getPlayer(player).actualizeLastTeleport();
if (Config.getInstance().getStatsTrackingEnabled()) {
MetricsManager.chimeraWingUsed();
}
@@ -119,13 +124,17 @@ public final class ChimaeraWing {
}
public static ItemStack getChimaeraWing(int amount) {
ItemStack itemStack = new ItemStack(Material.FEATHER, amount);
Material ingredient = Material.getMaterial(Config.getInstance().getChimaeraItemId());
ItemStack itemStack = new ItemStack(ingredient, amount);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName(ChatColor.GOLD + "Chimaera Wing"); //TODO Locale!
List<String> itemLore = new ArrayList<String>();
itemLore.add("mcMMO Item");
itemLore.add(ChatColor.GRAY + "Teleports you to your bed."); //TODO Locale!
itemMeta.setLore(itemLore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}

View File

@@ -13,6 +13,7 @@ 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;
public class ItemUtils {
private static Config configInstance = Config.getInstance();
@@ -535,7 +536,7 @@ public class ItemUtils {
* @return True if the item can be shared.
*/
public static boolean isShareable(ItemStack is) {
return isMiningDrop(is) || isWoodcuttingDrop(is) || isMobDrop(is) || isHerbalismDrop(is);
return isMiningDrop(is) || isWoodcuttingDrop(is) || isMobDrop(is) || isHerbalismDrop(is) || isMiscDrop(is);
}
/**
@@ -572,6 +573,12 @@ public class ItemUtils {
}
}
/**
* Checks to see if an item is a herbalism drop.
*
* @param is Item to check
* @return true if the item is a herbalism drop, false otherwise
*/
public static boolean isHerbalismDrop(ItemStack is) {
switch (is.getType()) {
case WHEAT:
@@ -586,7 +593,9 @@ 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;
@@ -599,6 +608,12 @@ public class ItemUtils {
}
}
/**
* Checks to see if an item is a mob drop.
*
* @param is Item to check
* @return true if the item is a mob drop, false otherwise
*/
public static boolean isMobDrop(ItemStack is) {
switch (is.getType()) {
case STRING:
@@ -635,6 +650,12 @@ public class ItemUtils {
}
}
/**
* Checks to see if an item is a woodcutting drop.
*
* @param is Item to check
* @return true if the item is a woodcutting drop, false otherwise
*/
public static boolean isWoodcuttingDrop(ItemStack is) {
switch (is.getType()) {
case LOG:
@@ -648,6 +669,16 @@ public class ItemUtils {
}
}
/**
* Checks to see if an item is a miscellaneous drop. These items are read from the config file
*
* @param is Item to check
* @return true if the item is a miscellaneous drop, false otherwise
*/
public static boolean isMiscDrop(ItemStack is) {
return ItemWeightConfig.getInstance().getMiscItems().contains(is.getType());
}
public static boolean isMcMMOItem(ItemStack is) {
if (!is.hasItemMeta()) {
return false;

View File

@@ -5,6 +5,7 @@ import java.util.Random;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -27,21 +28,23 @@ 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;
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 boolean isNPCEntity(Entity entity) {
return (entity == null || entity.hasMetadata("NPC") || (mcMMO.combatTagEnabled && entity instanceof HumanEntity && ((HumanEntity) entity).getName().contains("PvpLogger")));
}
/**

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