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

Compare commits

...

90 Commits

Author SHA1 Message Date
TfT_02
3b249aa4e6 This function is designed for API usage. 2014-10-11 12:03:08 +02:00
TfT_02
1a2d586086 More Javadocs 2014-10-11 11:53:12 +02:00
TfT_02
63b332216e Read summon item from config in /taming command 2014-10-11 11:38:53 +02:00
TfT_02
8e5340ebc3 Wolves attack a target when shot by their owner 2014-10-11 11:38:53 +02:00
TfT_02
e4af611c91 Fix formatting of TreeFeller threshold locale key 2014-10-11 11:38:52 +02:00
TfT_02
c31281971c Summon amount limits and new ability 2014-10-11 11:38:52 +02:00
TfT_02
eda38cba66 Add lifespan to Taming summons 2014-10-11 11:25:57 +02:00
TfT_02
b5a2e76926 Fixed diminished returns not getting disabled 2014-10-10 00:03:51 +02:00
TfT_02
38cc7435dc Prevent strings from getting larger than 16 chars
Fixes #2314
2014-10-04 20:31:37 +02:00
TfT_02
864a760e9c Better like this 2014-10-04 14:16:38 +02:00
TfT_02
0838cbb874 Add option to not show ability names on scoreboard
Adds #2249
2014-10-04 14:05:30 +02:00
TfT_02
4844be80da Fixed bug with Salvage and ability tools
Fixes #2311
2014-10-04 01:36:57 +02:00
TfT-02
62a767db89 Add enable toggle and per skill thresholds 2014-09-28 11:43:17 +02:00
TfT_02
ce3463ad6d Cleanup 2014-09-28 11:34:50 +02:00
TfT_02
5d059d8537 Move SkillXpGain to datatypes/experience 2014-09-28 11:34:49 +02:00
riking
332860b9ce Use a DelayQueue to manage rolling diminished returns 2014-09-28 11:34:49 +02:00
TfT_02
2a443cd9db Diminished instead of Deminished 2014-09-28 11:34:49 +02:00
NuclearW
f4d1004d32 Rolling xp diminishing returns
This adds on top of the diminishing returns system a mechanic such that gains will expire the configured number of minutes after they occured, rather than all being reset at once.

This prevents someone from not getting diminishing returns on the xp gain they recieved just before the reset would have occured.

Obligatory explanatory graphs: http://i.imgur.com/uSzicIR.png
2014-09-28 11:34:49 +02:00
TfT_02
9d8aec7eca Add diminished returns when a player has earned too much XP
When a player reaches a certain (configurable) threshold value of total
XP earned in a specific skill, his earned XP in this skill will be
decreased.

Depending on how far the player has exceeded the threshold value, his
XP will decrease more. After the (configurable) time interval of 10
minutes, the registered data will be cleared and the player can earn XP
as normal again.
2014-09-28 11:34:49 +02:00
Ivo Julca
958c116fd0 Acrobatics: cap same-location fall counter for XP gain
It used to increase boundlessly, thus preventing players from gaining XP for a while even after moving to another place.
2014-09-28 11:19:41 +02:00
Bestle
ec1a125809 These are the wrong way round
The UUID's are the keys, not the names
2014-09-28 11:13:23 +02:00
TfT_02
2dd8e719c8 UUID support for parties 2014-09-28 11:13:23 +02:00
TfT_02
d62c68a490 Fixes build 2014-09-28 11:08:57 +02:00
TfT_02
3c6dd290f4 Allow AdvancedSalvage unlock level 0
Fixes #2265
2014-09-06 20:23:41 +02:00
TfT_02
07e589aae3 Allow equal rank levels for Salvage
Fixes #2270
2014-09-06 19:59:26 +02:00
t00thpick1
1119d3c17f Actually fix flatfile player loading....
you lied to me @tft_02
2014-09-03 00:05:48 -04:00
TfT_02
eac5d1ee7a Improve auto mod config generator 2014-08-31 19:10:49 +02:00
TfT_02
56cb5c092f Should be this 2014-08-26 21:55:35 +02:00
Shevchik
9d7faf9ed9 Fix database loading data for wrong player
Fixes #2223
2014-08-24 15:25:56 -07:00
TfT_02
7da661546f Fixed bug where processing message would always get displayed
and the player could never execute /mctop or /mcrank if chat display
was disabled.
2014-08-24 09:21:40 -07:00
TfT_02
48d3280e5e Make sure that player has McMMOPlayer object before calling API 2014-08-22 15:50:40 -07:00
TfT_02
b61c65636b Add new ExperienceAPI method to specify if XP can be shared 2014-08-22 15:50:40 -07:00
TfT_02
087a0b079f Fixed bug with new Death API 2014-08-22 15:50:40 -07:00
t00thpick1
2147417322 This seems easier. 2014-08-22 15:16:40 -04:00
t00thpick1
4304970059 This was supposed to be a zero. 2014-08-22 00:59:20 -04:00
t00thpick1
fc981fda20 Better connection validation for us. 2014-08-21 19:42:03 -04:00
t00thpick1
be9ff51fd9 Should fix #2223 for realz this time. 2014-08-21 19:42:03 -04:00
TfT_02
adde56114e Cleanup the changelog 2014-08-21 16:40:06 -06:00
TfT_02
5cfd2dc799 Added API to ExperienceAPI to get the amount of XP needed for a level 2014-08-21 16:38:33 -06:00
TfT_02
c878775c72 Close the statement here as well 2014-08-21 14:33:50 -06:00
t00thpick1
574cdd374b Use a placeholder value. Fixes #2216 #2221 2014-08-20 22:19:36 -04:00
TfT_02
a3943aab24 Add checks for loaded/unloaded profiles in commands 2014-08-19 22:23:19 -06:00
t00thpick1
1503e58d11 More relevant donation information 2014-08-19 23:45:54 -04:00
TfT_02
2650d57d8e Added options to experience.yml for Dirt and Sand variations
Adds #2194
2014-08-19 21:28:53 -06:00
t00thpick1
4d402c7229 Use correct element 2014-08-19 19:11:07 -04:00
t00thpick1
d687543910 Prevent players from having more than one database querying command running at once. 2014-08-19 18:11:56 -04:00
t00thpick1
d8ad519cd0 Seperate pools for essential tasks like profile loading and profile saving. 2014-08-19 17:58:45 -04:00
TfT_02
a23d093271 Use provided instead of compile 2014-08-18 17:19:14 -06:00
TfT_02
8a35d69540 Move RefreshChunks setting from hidden.yml to config.yml
Adds #2213
2014-08-17 20:21:23 -06:00
t00thpick1
097a5a0894 Change purge a bit. Apparently andrewkm says this works. 2014-08-17 21:23:27 -04:00
t00thpick1
8760c2bbb0 This way is cleaner though. 2014-08-17 20:01:04 -04:00
t00thpick1
dc635fe7d7 SHould fix #2195 2014-08-17 19:57:52 -04:00
TfT_02
f10a1d0ffb Added McMMOPlayerPreDeathPenaltyEvent and McMMOPlayerStatLossEvent
McMMOPlayerPreDeathPenaltyEvent is fired before hardcore calculations
take place, use this if you want to cancel hardcore penalties.

Use McMMOPlayerVampirismEvent and McMMOPlayerStatLossEvent when you
want to know how many levels or experience the player lost or if you
want to modify this.
2014-08-16 21:13:46 -06:00
TfT_02
809779e508 Added McMMOPlayerVampirismEvent
Expands API possibilities regarding death penalty features.
2014-08-16 21:13:39 -06:00
TfT_02
80d358d1fd Fix dealing too much AOE damage
Bandaid for #2170
2014-08-13 21:24:32 -06:00
t00thpick1
a1be17c72c Add a rate limit for mojang api requests. Configurable via hidden.yml 2014-08-12 11:51:34 -04:00
t00thpick1
0a066f51bb Fix #2197 There is no wait forever option, so we actually need a timeout. 2014-08-12 11:39:43 -04:00
t00thpick1
294141c353 We should be reconnecting automagically. 2014-08-11 12:16:27 -04:00
t00thpick1
5a47f9fa86 Fix #1320 2014-08-08 00:42:33 -04:00
t00thpick1
6ee2d7d823 Do UUID saves in batches. 2014-08-08 00:13:30 -04:00
t00thpick1
f2881f02c8 Fix id retrieval 2014-08-08 00:09:00 -04:00
t00thpick1
9f5445689c Helpful debug on shutdown 2014-08-08 00:02:07 -04:00
t00thpick1
0ea163e3ee Lazy fix 2014-08-08 00:01:57 -04:00
t00thpick1
f097aa4a67 Missed loaded profile check, Fix #2189 2014-08-07 23:46:22 -04:00
t00thpick1
1fcb9e649e A bit more logic simplification in SQLDatabaseManager, also fixes error printing, Fix #2188 2014-08-07 23:45:40 -04:00
t00thpick1
1d0dc02013 Greatly simplify Profile loading in mySQL 2014-08-07 14:16:28 -04:00
t00thpick1
8766d31943 Fix #2182 and Fix #2178
NOW() is a numeric representation of the date, not a timestamp....  so thats a nono.

Also,  we need to update UUIDs grabbing by name.
2014-08-07 13:54:28 -04:00
t00thpick1
d857bf483e Fix #2184 2014-08-07 11:23:02 -04:00
t00thpick1
b7774251eb Remove need for thread locks in profile loading, just reschedule as needed. also stagger based on number of previous attempts. 2014-08-05 23:02:41 -04:00
t00thpick1
da7507fc75 Throw some sanity information into the info log. 2014-08-05 20:20:05 -04:00
t00thpick1
fe4699430d Fix #2177 2014-08-05 19:15:22 -04:00
t00thpick1
df4fc8149d Stagger load attempts more. 2014-08-05 19:03:55 -04:00
t00thpick1
c156f0c346 Missed an unlock condition, lets use a finally. Should Fix #2180 2014-08-05 18:57:13 -04:00
t00thpick1
79a17b0c1c Fix /mcrank when using flatfile. Fixes #2179 2014-08-05 09:20:12 -04:00
t00thpick1
d3051ad127 Use a slight delay to ensure its after the purge. 2014-08-04 11:49:09 -04:00
t00thpick1
f4c53aaf8a Prevent user purges and UUID updates from conflicting in mass database operations. 2014-08-04 11:42:02 -04:00
t00thpick1
432ff95a98 More constants 2014-08-04 11:40:47 -04:00
t00thpick1
fe29bb4b9f Accurate purge count 2014-08-03 21:14:24 -04:00
t00thpick1
ae5347bc0f Purging shouldn't be main thread, also we have no reason to refresh profiles of purged users, as old users aren't online, and powerless users have nothing to wipe. 2014-08-03 21:12:41 -04:00
t00thpick1
966de87ef9 Print reason 2014-08-03 20:57:28 -04:00
t00thpick1
3569f9a182 Woot, rushing things without looking! 2014-08-03 20:40:48 -04:00
t00thpick1
70a23f8a0a EnumMaps cannot use a null key 2014-08-03 20:39:37 -04:00
t00thpick1
857e12b96e SQLDatabaseManager optimizations, async profile loading -t00thpick1, zreed
This commit changes our shared connection into a connection pool utility to prevent
thread locks from multiple actions attempting to access the database at the same time.
In additon,  profile loading has been moved off the main thread at login time, to
allieviate the performance issues caused by it.

Fixes #2138, Fixes #2119, Fixes #1982, Fixes #1953
2014-08-01 20:31:17 +02:00
TfT_02
c10525ada9 Add UUID support! - zreed, slipcor, t00thpick1
This commit updates our database managers to use UUIDs instead
of usernames for persistent storage.

Fixes #1979
2014-08-01 20:23:03 +02:00
TfT_02
fb8592495d Only set detected durability if it's > 0 2014-08-01 01:09:00 +02:00
TfT_02
a48ada306c Add magical mod importer
Usage: Create a folder called 'import' inside /mcMMO/mods/. Place your latest Cauldron 1.7+ startup log in this folder and rename it to 'import.log'.
It is worth noting that it's advisable to create a short log by starting and stopping the server once, or by manually editing the log file to only include material mapping in order to speed up the import process.

When the server is running, use the command /mcimport. You will see the import progress in the console, once it is done the files are created in /mcMMO/mods/output/.

Any item that wasn't recognised gets placed in a .unknown.yml config file. Durability detection only works if the mod is installed when importing (it should be).
2014-08-01 00:22:29 +02:00
Lucas Savva
8db0d663dc More configs for 1.6.X mods
+ Added full tools and armor and some block configs for:
- Advanced Genetics
- Applied Energistcs
- Big Reactors
- Biomes O Plenty
- Emasher Resource
- Extra Utilities
- Factorization
- Forestry
- MineFactory Reloaded
- Natura
- Project Red
- Railcraft
- StargateTech 2
- Thermal Expansion
- Tinker's Construct
- Twilight Forest
2014-07-31 16:56:41 +01:00
TfT_02
70744371a3 Fix bug where Repair_Material_Quantity wasn't read 2014-07-31 00:47:22 +02:00
TfT_02
18c322e8d6 Check if the user wants this item repairable first
Stop complaining that the item is not repairable when Repairable is set
to false.
2014-07-31 00:46:41 +02:00
TfT_02
75cbfa1b1c Ensure player has mcMMOPlayer object in brewing
Fixes #2086
2014-07-24 12:29:42 +02:00
144 changed files with 5926 additions and 1468 deletions

View File

@@ -9,15 +9,27 @@ Key:
Version 1.5.01-dev
+ Added new child skill; Salvage
+ Added UUID support!
+ Added SQL connection pooling and async loading!
+ Added the long awaited Diminished Returns feature
+ Added new feature to Herbalism. Instantly-regrown crops are protected from being broken for 1 second
+ Added option to config.yml to show the /mcstats scoreboard automatically after logging in
+ Added option to config.yml for Alchemy. Skills.Alchemy.Prevent_Hopper_Transfer_Bottles
+ Added option to config.yml for Scoreboards, display "Ability" instead of ability names on the scoreboards
+ Added options to experience.yml for Dirt and Sand variations
+ Added support for `MATERIAL|data` format in treasures.yml
+ Added API to experience events to get XP gain reason
+ Added API to check if an entity is bleeding
+ Added API to ExperienceAPI to get the amount of XP needed for a level
+ Added API class SkillAPI used to get a list of valid skill names
+ Added API events for hardcore features, McMMOPlayerPreDeathPenaltyEvent, McMMOPlayerStatLossEvent and McMMOPlayerVampirismEvent
+ Added API to ExperienceAPI to specify if XP can be shared
+ Added options to tools.yml and armor.yml config files to set a pretty repair material name
+ Added full support for repairables in tools.yml and armor.yml config files
+ Added new API class SkillAPI used to get a list of valid skill names
+ Added magical mod config file import command, for Cauldron 1.7+. Check wiki for usage
+ Added particle effects and sounds to "Call of the Wild" (Taming)
+ Added summon length to "Call of the Wild". Summons will now commit suicide after their lifespan expires
+ Added feature which makes tamed wolves attack a target shot by the owner
= Fixed bug where pistons would mess with the block tracking
= Fixed bug where the Updater was running on the main thread.
= Fixed bug when players would use /ptp without being in a party
@@ -35,6 +47,7 @@ Version 1.5.01-dev
= Fixed bug where party chat was using non thread safe methods
= Fixed bug where Blast Mining unlock levels could be to high in certain occasions
= Fixed bug where Blast Minings ability "Demolition Expert" would not work
= Fixed bug where Repair_Material_Quantity wasn't read in mod config files
! Changed SecondaryAbilityEvent to implement Cancellable and it now gets fired for damage related secondary abilities
! Changed the way mcMMO handles bonus damage, updated for the new damage event API
! Changed player data saving. Save tasks are now asynchronous
@@ -43,6 +56,8 @@ Version 1.5.01-dev
! Changed Alchemy XP distribution. XP is granted based on the stage of the potion.
! Changed behavior of the Blast Mining ability "Demolition Expert"; now only decreases damage for the ability user
! Updated for new getOnlinePlayers() behavior
! Changed McMMOPlayerDeathPenaltyEvent to get fired after hardcore penalty calculations, use McMMOPlayerPreDeathPenaltyEvent for old behavior
! Moved Refresh_Chunks setting from hidden.yml to config.yml
- Removed salvage ability from Repair, salvage has it's own (child) skill now
Version 1.5.00

View File

@@ -0,0 +1,14 @@
# Config wrote by M1cr0man
# Up to date as of Advanced Genetics 1.4.3
Bows:
# Genetic
X31179:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31197
Repair_Material_Pretty_Name: "Cell"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 1501

View File

@@ -0,0 +1,9 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Applied Energistics rv14-finale3
Mining:
# Certus Quartz Ore
X4076|0:
XP_Gain: 250
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,65 @@
# Config wrote by M1cr0man
# Up to date as of Applied Energistics rv14-finale3
Axes:
# Quartz
X4365:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X4362
Repair_Material_Pretty_Name: "Certus Quartz"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 3
Durability: 250
Hoes:
# Quartz
X4366:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X4362
Repair_Material_Pretty_Name: "Certus Quartz"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 2
Pickaxes:
# Quartz
X4368:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X4362
Repair_Material_Pretty_Name: "Certus Quartz"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 3
Durability: 250
Shovels:
# Quartz
X4367:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X4362
Repair_Material_Pretty_Name: "Certus Quartz"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 1
Durability: 750
Swords:
# Quartz
X4369:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X4362
Repair_Material_Pretty_Name: "Certus Quartz"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 2
Durability: 250

View File

@@ -0,0 +1,9 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Big Reactors 0.3.4A2
Mining:
# Yellorite
X1750|0:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,77 @@
# Config wrote by M1cr0man
# Up to date as of BoP 1.2.1.434
Boots:
# Wading
X21269:
Repairable: false
Durability: 9999
# Muddy
X21283:
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 4
Durability: 26
# Amethyst
X21293:
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 4
Durability: 520
Chestplates:
# Muddy
X21281:
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 8
Durability: 32
# Amethyst
X21291:
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 8
Durability: 640
Helmets:
# Muddy
X21280:
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 5
Durability: 22
# Amethyst
X21290:
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 5
Durability: 440
Leggings:
# Muddy
X21280:
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 7
Durability: 30
# Amethyst
X21290:
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 7
Durability: 600

View File

@@ -0,0 +1,44 @@
# Config wrote by M1cr0man
# Incomplete! Only covers ores
# Up to date as of BoP 1.2.1.434
Mining:
# Red Rock
X162|0:
XP_Gain: 30
Double_Drops_Enabled: true
Is_Ore: false
# Amethyst
X1921|0:
XP_Gain: 200
Double_Drops_Enabled: true
Is_Ore: true
# Ruby
X1921|2:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Peridot
X1921|4:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Topaz
X1921|6:
XP_Gain: 200
Double_Drops_Enabled: true
Is_Ore: true
# Tanzanite
X1921|8:
XP_Gain: 200
Double_Drops_Enabled: true
Is_Ore: true
# Malachite
X1921|10:
XP_Gain: 200
Double_Drops_Enabled: true
Is_Ore: true
# Sapphire
X1921|12:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,121 @@
# Config wrote by M1cr0man
# Up to date as of BoP 1.2.1.434
Axes:
# Amethyst
X21287:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 2013
# Muddy
X21277:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 32
Hoes:
# Amethyst
X21288:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 2013
# Muddy
X21278:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 32
Pickaxes:
# Amethyst
X21286:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 2013
# Muddy
X21276:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 32
Shovels:
# Amethyst
X21285:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 1
Durability: 2013
# Muddy
X21275:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 1
Durability: 32
Swords:
# Amethyst
X21284:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X21264
Repair_Material_Pretty_Name: "Amethyst"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 2013
# Muddy
X21274:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X21263
Repair_Material_Pretty_Name: "Mud Ball"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 32

View File

@@ -0,0 +1,31 @@
# Config wrote by M1cr0man
# Up to date as of Emasher Resource 1.2.3.5
Boots:
# Hemp
X9301:
Repairable: true
Repair_Material: X9291
Repair_Material_Pretty_Name: "Hemp"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 4
Durability: 65
Chestplates:
# Hemp
X9299:
Repairable: true
Repair_Material: X9291
Repair_Material_Pretty_Name: "Hemp"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 8
Durability: 80
Leggings:
# Hemp
X9300:
Repairable: true
Repair_Material: X9291
Repair_Material_Pretty_Name: "Hemp"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 7
Durability: 75

View File

@@ -0,0 +1,44 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Emasher Resource 1.2.3.5
Mining:
# Bauxite
X1565|0:
XP_Gain: 250
Double_Drops_Enabled: true
Is_Ore: true
# Cassiterite
X1565|1:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Emery
X1565|2:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Galena
X1565|3:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true
# Native Copper
X1565|4:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Petlandite
X1565|5:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true
# Ruby
X1565|6:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Sapphire
X1565|7:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,54 @@
# Config wrote by M1cr0man
# Up to date as of Extra Utilities 1.0.3c
Axes:
# Healing
X10264:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X10258
Repair_Material_Pretty_Name: "Unstable Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 1561
Hoes:
# Reversing
X10265:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: true
Repair_Material: X10258
Repair_Material_Pretty_Name: "Unstable Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 1561
Pickaxes:
# Destruction
X10263:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: false
Durability: 6244
Shovels:
# Erosion
X10262:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: false
Durability: 6244
Swords:
# Etheric
X10261:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 4
Repairable: false
Durability: 1561

View File

@@ -0,0 +1,9 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Factorization 0.8.34
Mining:
# Dark Iron Ore
X1004|0:
XP_Gain: 250
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,19 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Forestry 2.3.1.1
Mining:
# Apatite
X1398|0:
XP_Gain: 100
Double_Drops_Enabled: true
Is_Ore: true
# Copper
X1398|1:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Tin
X1398|2:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,27 @@
# Config wrote by M1cr0man
# Up to date as of Forestry 2.3.1.1
Pickaxes:
# Survivalist
X13261:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X5261
Repair_Material_Pretty_Name: "Bronze Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 200
Shovels:
# Survivalist
X13264:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X5261
Repair_Material_Pretty_Name: "Bronze Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 200

View File

@@ -0,0 +1,11 @@
# Config wrote by M1cr0man
# Up to date as of Minefactory Reloaded 2.7.9 Final
Boots:
# Plastic
X12306:
Repairable: true
Repair_Material: X12249
Repair_Material_Pretty_Name: "Plastic Sheets"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 4
Durability: 39

View File

@@ -0,0 +1,41 @@
# Config wrote by M1cr0man
# Up to date as of Natura 2.1.14
Boots:
# Impskin
X12712:
Repairable: true
Repair_Material: X12660
Repair_Material_Pretty_Name: "Imp Leather"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 4
Durability: 429
Chestplates:
# Impskin
X12710:
Repairable: true
Repair_Material: X12660
Repair_Material_Pretty_Name: "Imp Leather"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 8
Durability: 528
Helmets:
# Impskin
X12709:
Repairable: true
Repair_Material: X12660
Repair_Material_Pretty_Name: "Imp Leather"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 5
Durability: 363
Leggings:
# Impskin
X12709:
Repairable: true
Repair_Material: X12660
Repair_Material_Pretty_Name: "Imp Leather"
Repair_Material_Data_Value: 6
Repair_Material_Quantity: 7
Durability: 495

View File

@@ -0,0 +1,272 @@
# Config wrote by M1cr0man
# Up to date as of Natura 2.1.14
Axes:
# Bloodwood
X12685:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Bloodwood Planks"
Repair_Material_Data_Value: 4
Repair_Material_Quantity: 3
Durability: 350
# Darkwood
X12689:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Darkwood Planks"
Repair_Material_Data_Value: 11
Repair_Material_Quantity: 3
Durability: 131
# Fusewood
X12693:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Fusewood Planks"
Repair_Material_Data_Value: 12
Repair_Material_Quantity: 3
Durability: 250
# Ghostwood
X12681:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Ghostwood Planks"
Repair_Material_Data_Value: 2
Repair_Material_Quantity: 3
Durability: 59
# Quartz
X12697:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: QUARTZ_BLOCK
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 131
Bows:
# Bloodwood
X12706:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X12677
Repair_Material_Pretty_Name: "Bloodwood Stick"
Repair_Material_Data_Value: 4
Repair_Material_Quantity: 3
Durability: 1501
# Darkwood
X12707:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X12677
Repair_Material_Pretty_Name: "Darkwood Stick"
Repair_Material_Data_Value: 11
Repair_Material_Quantity: 3
Durability: 162
# Fusewood
X12708:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X12677
Repair_Material_Pretty_Name: "Fusewood Stick"
Repair_Material_Data_Value: 12
Repair_Material_Quantity: 3
Durability: 28
# Ghostwood
X12705:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X12677
Repair_Material_Pretty_Name: "Ghostwood Stick"
Repair_Material_Data_Value: 2
Repair_Material_Quantity: 3
Durability: 384
Pickaxes:
# Bloodwood
X12683:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Bloodwood Planks"
Repair_Material_Data_Value: 4
Repair_Material_Quantity: 3
Durability: 350
# Darkwood
X12687:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Darkwood Planks"
Repair_Material_Data_Value: 11
Repair_Material_Quantity: 3
Durability: 131
# Fusewood
X12691:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Fusewood Planks"
Repair_Material_Data_Value: 12
Repair_Material_Quantity: 3
Durability: 250
# Ghostwood
X12679:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Ghostwood Planks"
Repair_Material_Data_Value: 2
Repair_Material_Quantity: 3
Durability: 59
# Quartz
X12695:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: QUARTZ_BLOCK
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 3
Durability: 131
Shovels:
# Bloodwood
X12684:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Bloodwood Planks"
Repair_Material_Data_Value: 4
Repair_Material_Quantity: 1
Durability: 350
# Darkwood
X12688:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Darkwood Planks"
Repair_Material_Data_Value: 11
Repair_Material_Quantity: 1
Durability: 131
# Fusewood
X12692:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Fusewood Planks"
Repair_Material_Data_Value: 12
Repair_Material_Quantity: 1
Durability: 250
# Ghostwood
X12680:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Ghostwood Planks"
Repair_Material_Data_Value: 2
Repair_Material_Quantity: 1
Durability: 59
# Quartz
X12696:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: QUARTZ_BLOCK
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 1
Durability: 131
Swords:
# Bloodwood
X12682:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Bloodwood Planks"
Repair_Material_Data_Value: 4
Repair_Material_Quantity: 2
Durability: 350
# Darkwood
X12686:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Darkwood Planks"
Repair_Material_Data_Value: 11
Repair_Material_Quantity: 2
Durability: 131
# Fusewood
X12690:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Fusewood Planks"
Repair_Material_Data_Value: 12
Repair_Material_Quantity: 2
Durability: 250
# Ghostwood
X12678:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: X3262
Repair_Material_Pretty_Name: "Ghostwood Planks"
Repair_Material_Data_Value: 2
Repair_Material_Quantity: 2
Durability: 59
# Quartz
X12694:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: true
Repair_Material: QUARTZ_BLOCK
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 131

View File

@@ -0,0 +1,29 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Project Red 4.3.5.30
Mining:
# Ruby
X2130|0:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Sapphire
X2130|1:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Peridot
X2130|2:
XP_Gain: 350
Double_Drops_Enabled: true
Is_Ore: true
# Marble
X2131|0:
XP_Gain: 30
Double_Drops_Enabled: true
Is_Ore: false
# Basalt
X2131|3:
XP_Gain: 30
Double_Drops_Enabled: true
Is_Ore: false

View File

@@ -0,0 +1,176 @@
# Config wrote by M1cr0man
# Up to date as of Project Red 4.3.5.30
Axes:
# Ruby
X9353:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Ruby"
Repair_Material_Data_Value: 37
Repair_Material_Quantity: 3
Durability: 500
# Sapphire
X9354:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Sapphire"
Repair_Material_Data_Value: 38
Repair_Material_Quantity: 3
Durability: 500
# Peridot
X9355:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Peridot"
Repair_Material_Data_Value: 39
Repair_Material_Quantity: 3
Durability: 500
Hoes:
# Ruby
X9356:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Ruby"
Repair_Material_Data_Value: 37
Repair_Material_Quantity: 2
Durability: 500
# Sapphire
X9357:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Sapphire"
Repair_Material_Data_Value: 38
Repair_Material_Quantity: 2
Durability: 500
# Peridot
X9358:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Peridot"
Repair_Material_Data_Value: 39
Repair_Material_Quantity: 2
Durability: 500
Pickaxes:
# Ruby
X9359:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Ruby"
Repair_Material_Data_Value: 37
Repair_Material_Quantity: 3
Durability: 500
# Sapphire
X9360:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Sapphire"
Repair_Material_Data_Value: 38
Repair_Material_Quantity: 3
Durability: 500
# Peridot
X9361:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Peridot"
Repair_Material_Data_Value: 39
Repair_Material_Quantity: 3
Durability: 500
Shovels:
# Ruby
X9362:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Ruby"
Repair_Material_Data_Value: 37
Repair_Material_Quantity: 1
Durability: 500
# Sapphire
X9363:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Sapphire"
Repair_Material_Data_Value: 38
Repair_Material_Quantity: 1
Durability: 500
# Peridot
X9364:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Peridot"
Repair_Material_Data_Value: 39
Repair_Material_Quantity: 1
Durability: 500
Swords:
# Ruby
X9365:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Ruby"
Repair_Material_Data_Value: 37
Repair_Material_Quantity: 2
Durability: 500
# Sapphire
X9366:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Sapphire"
Repair_Material_Data_Value: 38
Repair_Material_Quantity: 2
Durability: 500
# Peridot
X9368:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X9281
Repair_Material_Pretty_Name: "Peridot"
Repair_Material_Data_Value: 39
Repair_Material_Quantity: 2
Durability: 500

View File

@@ -1,44 +1,49 @@
# Config created by Dragyn
# Created For Railcraft_1.6.2-8.1.0.0
#
#
# Settings for Boots
###
# Config wrote by Dragyn, updated by M1cr0man
# Up to date as of Railcraft 8.4.0.0
Boots:
# Steel
X7758:
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Chestplates
###
Repair_Material_Quantity: 4
Durability: 325
Chestplates:
# Steel
X7761:
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Helmets
###
Repair_Material_Quantity: 8
Durability: 400
Helmets:
# Steel
X7759:
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Leggings
###
Repair_Material_Quantity: 5
Durability: 275
Leggings:
# Steel
X7760:
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 7
Durability: 375
# Overalls
X7757:
Repairable: true
Repair_Material: WOOL
Repair_Material_Pretty_Name: "Light Blue Wool"
Repair_Material_Data_Value: 3
Repair_Material_Quantity: 7
Durability: 75

View File

@@ -1,76 +1,66 @@
# Config created by Dragyn
# Created For Railcraft_1.6.2-8.1.0.0
#
#
# Settings for Axes
###
# Config wrote by Dragyn, updated by M1cr0man
# Up to date as of Railcraft 8.4.0.0
Axes:
# Steel
X7819:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Hoes
###
Hoes:
# Steel
X7820:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Pickaxes
###
Pickaxes:
# Steel
X7821:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Shovels
###
Shovels:
# Steel
X7823:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Swords
###
Swords:
# Steel
X7824:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X7796
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 500

View File

@@ -0,0 +1,9 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Stargate Tech 2 Alpha 0.7.3
Mining:
# Naquadah Ore
X1005|0:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,41 @@
# Config wrote by M1cr0man
# Up to date as of Thermal Expansion 3.0.0.7
Boots:
# Invar
X31973:
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 4
Durability: 325
Chestplates:
# Invar
X31975:
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 8
Durability: 400
Helmets:
# Invar
X31976:
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 5
Durability: 275
Leggings:
# Invar
X31976:
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 7
Durability: 375

View File

@@ -0,0 +1,29 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Thermal Expansion 3.0.0.7
Mining:
# Copper
X4064|0:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Tin
X4064|1:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Silver
X4064|2:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true
# Lead
X4064|3:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true
# Ferrous
X4064|4:
XP_Gain: 300
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,66 @@
# Config wrote by M1cr0man
# Up to date as of Thermal Expansion 3.0.0.7
Axes:
# Invar
X31969:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 3
Durability: 450
Hoes:
# Invar
X31968:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 2
Durability: 450
Pickaxes:
# Invar
X31970:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 3
Durability: 450
Shovels:
# Invar
X31971:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 1
Durability: 450
Swords:
# Invar
X31972:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 3
Repairable: true
Repair_Material: X31978
Repair_Material_Pretty_Name: "Invar Ingot"
Repair_Material_Data_Value: 71
Repair_Material_Quantity: 2
Durability: 450

View File

@@ -0,0 +1,74 @@
# Config wrote by M1cr0man
# Up to date as of Tinker's Construct 1.5.5.7
# Also covers Tinker's Steelworks 0.0.4.2-fix2
Boots:
# Wooden (Repaired with Oak Wood)
X14366:
Repairable: true
Repair_Material: LOG
Repair_Material_Pretty_Name: "Oak Wood"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 4
Durability: 26
# Steel
X14771:
Repairable: true
Repair_Material: X14276
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 16
Repair_Material_Quantity: 4
Durability: 325
Chestplates:
# Wooden (Repaired with Oak Wood)
X14364:
Repairable: true
Repair_Material: LOG
Repair_Material_Pretty_Name: "Oak Wood"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 8
Durability: 32
# Steel
X14769:
Repairable: true
Repair_Material: X14276
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 16
Repair_Material_Quantity: 8
Durability: 400
Helmets:
# Wooden (Repaired with Oak Wood)
X14362:
Repairable: true
Repair_Material: LOG
Repair_Material_Pretty_Name: "Oak Wood"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 5
Durability: 22
# Steel
X14768:
Repairable: true
Repair_Material: X14276
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 16
Repair_Material_Quantity: 5
Durability: 275
Leggings:
# Wooden (Repaired with Oak Wood)
X14362:
Repairable: true
Repair_Material: LOG
Repair_Material_Pretty_Name: "Oak Wood"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 7
Durability: 30
# Steel
X14768:
Repairable: true
Repair_Material: X14276
Repair_Material_Pretty_Name: "Steel Ingot"
Repair_Material_Data_Value: 16
Repair_Material_Quantity: 7
Durability: 375

View File

@@ -0,0 +1,55 @@
# Config wrote by M1cr0man
# Possibly incomplete. Only covers ores
# Up to date as of Tinker's Construct 1.5.5.7
Excavation:
# Iron
X1488|0:
XP_Gain: 250
Double_Drops_Enabled: true
# Gold
X1488|1:
XP_Gain: 350
Double_Drops_Enabled: true
# Copper
X1488|2:
XP_Gain: 175
Double_Drops_Enabled: true
# Tin
X1488|3:
XP_Gain: 175
Double_Drops_Enabled: true
# Aluminum
X1488|4:
XP_Gain: 250
Double_Drops_Enabled: true
# Cobalt
X1488|5:
XP_Gain: 500
Double_Drops_Enabled: true
Mining:
# Cobalt
X1475|1:
XP_Gain: 500
Double_Drops_Enabled: true
Is_Ore: true
# Ardite
X1475|2:
XP_Gain: 500
Double_Drops_Enabled: true
Is_Ore: true
# Copper
X1475|3:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Tin
X1475|4:
XP_Gain: 175
Double_Drops_Enabled: true
Is_Ore: true
# Aluminium
X1475|5:
XP_Gain: 250
Double_Drops_Enabled: true
Is_Ore: true

View File

@@ -0,0 +1,149 @@
# Config wrote by M1cr0man
# Abilites for Pickaxes and Shovels disabled due to a bug
# Repair disabled as mcMMO does not support NBTTag - based tools
# Up to date as of Tinker's Construct 1.5.5.7
# Also covers Tinker's Steelworks 0.0.4.2-fix2
Axes:
# Hatchets
X14309:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Mattocks
X14316:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Lumber Axes
X14317:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Battle Axes
X14327:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
Bows:
# Shortbows
X14319:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
Hoes:
# Mattocks
X14316:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Scythes
X14323:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
Pickaxes:
# Pickaxes
X14307:
XP_Modifier: 1.0
Ability_Enabled: false
Tier: 2
Repairable: false
Durability: 500
# Hammers
X14326:
XP_Modifier: 1.0
Ability_Enabled: false
Tier: 2
Repairable: false
Durability: 500
Shovels:
# Shovels
X14308:
XP_Modifier: 1.0
Ability_Enabled: false
Tier: 2
Repairable: false
Durability: 500
# Mattocks
X14316:
XP_Modifier: 1.0
Ability_Enabled: false
Tier: 2
Repairable: false
Durability: 500
# Excavators
X14325:
XP_Modifier: 1.0
Ability_Enabled: false
Tier: 2
Repairable: false
Durability: 500
Swords:
# Broadswords
X14311:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Longswords
X14312:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Rapiers
X14313:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Daggers
X14321:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Cleavers
X14324:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Battle Axes
X14327:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500
# Cutlasses
X14328:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 2
Repairable: false
Durability: 500

View File

@@ -1,134 +1,161 @@
# Config created by Dragyn
# Created For twilightforest-1.20.3
#
#
# Settings for Boots
###
Boots:
# Config wrote by Dragyn, updated by M1cr0man
# Up to date as of Twilight Forest 1.20.5
Boots:
# Ironwood
X27978:
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 4
Durability: 260
# Fiery
X27995:
Repairable: true
Repair_Material: X27991
Repair_Material_Pretty_Name: "Fiery Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 4
Durability: 325
# Stealeaf
X28002:
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 4
Durability: 260
# Knightmetal
X28037:
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Chestplates
###
Repair_Material_Quantity: 4
Durability: 260
Chestplates:
# Ironwood
X27976:
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 8
Durability: 320
# Naga Scale
X27958:
Repairable: true
Repair_Material: X27957
Repair_Material_Pretty_Name: "Naga Scale"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 8
Durability: 336
# Fiery
X27993:
Repairable: true
Repair_Material: X27991
Repair_Material_Pretty_Name: "Fiery Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 8
Durability: 400
# Stealeaf
X28000:
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 8
Durability: 320
# Knightmetal
X28035:
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 8
Durability: 320
# Phantom
X28035:
Repairable: false
Durability: 480
#
# Settings for Helmets
###
Helmets:
# Ironwood
X27975:
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 5
Durability: 220
# Fiery
X27992:
Repairable: true
Repair_Material: X27991
Repair_Material_Pretty_Name: "Fiery Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 5
Durability: 275
# Stealeaf
X27999:
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 5
Durability: 220
# Knightmetal
X28034:
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 5
Durability: 220
# Phantom
X28034:
Repairable: false
Durability: 330
#
# Settings for Leggings
###
Leggings:
# Ironwood
X27977:
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 7
Durability: 300
# Naga Scale
X27959:
Repairable: true
Repair_Material: X27957
Repair_Material_Pretty_Name: "Naga Scale"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 7
Durability: 315
# Fiery
X27994:
Repairable: true
Repair_Material: X27991
Repair_Material_Pretty_Name: "Fiery Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 7
Durability: 375
# Stealeaf
X28001:
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 7
Durability: 300
# Knightmetal
X28036:
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repair_Material_Quantity: 7
Durability: 300

View File

@@ -1,186 +1,181 @@
# Config created by Dragyn
# Created For twilightforest-1.20.3
#
#
# Settings for Axes
###
# Config wrote by Dragyn, updated by M1cr0man
# Up to date as of Twilight Forest 1.20.5
Axes:
# Ironwood
X27982:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Steeleaf
X31989:
XP_Modifer: 1.0
X28006:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 131
# Knightmetal
X28040:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Minotaur
X31984:
XP_Modifer: 1.0
X28008:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X264
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Repairable: false
Durability: 1561
#
# Settings for Hoes
###
Hoes:
# Ironwood
X27983:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Steeleaf
X31988:
XP_Modifer: 1.0
X28007:
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 131
#
# Settings for Pickaxes
###
Pickaxes:
# Ironwood
X27981:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Fiery
X27997:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27991
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 1024
# Steeleaf
X28005:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 131
# Knightmetal
X28039:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Shovels
###
Durability: 512
Shovels:
# Ironwood
X27980:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Steeleaf
X28004:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
#
# Settings for Swords
###
Durability: 131
Swords:
# Ironwood
X27979:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27974
Repair_Material_Pretty_Name: "Ironwood Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512
# Fiery
X27996:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27991
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 1024
# Steeleaf
X28003:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X27998
Repair_Material_Pretty_Name: "Steeleaf"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 131
# Knightmetal
X28038:
XP_Modifer: 1.0
XP_Modifier: 1.0
Ability_Enabled: true
Tier: 1
Repairable: true
Repair_Material: X28032
Repair_Material_Pretty_Name: "Knightmetal Ingot"
Repair_Material_Data_Value: 0
Repair_Material_Quantity: 2
Durability: 500
Durability: 512

19
pom.xml
View File

@@ -76,6 +76,8 @@
<artifactSet>
<includes>
<include>com.turt2live.metrics:MetricsExtension</include>
<include>commons-logging:commons-logging</include>
<include>net.snaq:dbpool</include>
</includes>
</artifactSet>
<relocations>
@@ -83,6 +85,14 @@
<pattern>com.turt2live.metrics</pattern>
<shadedPattern>com.gmail.nossr50.metrics.mcstats</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.logging</pattern>
<shadedPattern>com.gmail.nossr50.commons.logging</shadedPattern>
</relocation>
<relocation>
<pattern>net.snaq</pattern>
<shadedPattern>com.gmail.nossr50.dbpool</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -121,9 +131,9 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>LATEST</version>
<version>1.7.10-R0.1-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -136,6 +146,11 @@
<artifactId>MetricsExtension</artifactId>
<version>0.0.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.snaq</groupId>
<artifactId>dbpool</artifactId>
<version>5.1</version>
</dependency>
</dependencies>
<distributionManagement>
<repository>

View File

@@ -11,34 +11,106 @@ import com.gmail.nossr50.util.player.UserManager;
public final class AbilityAPI {
private AbilityAPI() {}
/**
* Checks if the ability "Berserk" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Berserk" is active
*/
public static boolean berserkEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.BERSERK);
}
/**
* Checks if the ability "Giga Drill Breaker" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Giga Drill Breaker" is active
*/
public static boolean gigaDrillBreakerEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.GIGA_DRILL_BREAKER);
}
/**
* Checks if the ability "Green Terra" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Green Terra" is active
*/
public static boolean greenTerraEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.GREEN_TERRA);
}
/**
* Checks if the ability "Serrated Strikes" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Serrated Strikes" is active
*/
public static boolean serratedStrikesEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SERRATED_STRIKES);
}
/**
* Checks if the ability "Skull Splitter" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Skull Splitter" is active
*/
public static boolean skullSplitterEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SKULL_SPLITTER);
}
/**
* Checks if the ability "Super Breaker" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Super Breaker" is active
*/
public static boolean superBreakerEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SUPER_BREAKER);
}
/**
* Checks if the ability "Tree Feller" is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if "Tree Feller" is active
*/
public static boolean treeFellerEnabled(Player player) {
return UserManager.getPlayer(player).getAbilityMode(AbilityType.TREE_FELLER);
}
/**
* Checks if any ability is active.
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to check
*
* @return true if any ability is active
*/
public static boolean isAnyAbilityEnabled(Player player) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
@@ -51,38 +123,110 @@ public final class AbilityAPI {
return false;
}
/**
* Reset the ability cooldowns for a player
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to reset the cooldowns for
*/
public static void resetCooldowns(Player player) {
UserManager.getPlayer(player).resetCooldowns();
}
/**
* Set the cooldown for the "Berserk" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setBerserkCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.BERSERK, cooldown);
}
/**
* Set the cooldown for the "Giga Drill Breaker" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setGigaDrillBreakerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.GIGA_DRILL_BREAKER, cooldown);
}
/**
* Set the cooldown for the "Green Terra" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setGreenTerraCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.GREEN_TERRA, cooldown);
}
/**
* Set the cooldown for the "Serrated Strikes" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setSerratedStrikesCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SERRATED_STRIKES, cooldown);
}
/**
* Set the cooldown for the "Skull Splitter" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setSkullSplitterCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SKULL_SPLITTER, cooldown);
}
/**
* Set the cooldown for the "Super Breaker" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setSuperBreakerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SUPER_BREAKER, cooldown);
}
/**
* Set the cooldown for the "Tree Feller" ability
* </br>
* This function is designed for API usage.
*
* @param player The {@link Player} to set the cooldown for
* @param cooldown The cooldown length to set
*/
public static void setTreeFellerCooldown(Player player, long cooldown) {
UserManager.getPlayer(player).setAbilityDATS(AbilityType.TREE_FELLER, cooldown);
}
/**
* Check if a LivingEntity is bleeding
* </br>
* This function is designed for API usage.
*
* @param entity The {@link LivingEntity} to check
* @return true if entity is bleeding, false otherwise
*/
public static boolean isBleeding(LivingEntity entity) {
return BleedTimerTask.isBleeding(entity);
}

View File

@@ -71,6 +71,8 @@ public final class ChatAPI {
/**
* Check if a player is currently talking in party chat.
* </br>
* This function is designed for API usage.
*
* @param player The player to check
* @return true if the player is using party chat, false otherwise
@@ -81,6 +83,8 @@ public final class ChatAPI {
/**
* Check if a player is currently talking in party chat.
* </br>
* This function is designed for API usage.
*
* @param playerName The name of the player to check
* @return true if the player is using party chat, false otherwise
@@ -91,6 +95,8 @@ public final class ChatAPI {
/**
* Check if a player is currently talking in admin chat.
* </br>
* This function is designed for API usage.
*
* @param player The player to check
* @return true if the player is using admin chat, false otherwise
@@ -101,6 +107,8 @@ public final class ChatAPI {
/**
* Check if a player is currently talking in admin chat.
* </br>
* This function is designed for API usage.
*
* @param playerName The name of the player to check
* @return true if the player is using admin chat, false otherwise
@@ -111,6 +119,8 @@ public final class ChatAPI {
/**
* Toggle the party chat mode of a player.
* </br>
* This function is designed for API usage.
*
* @param player The player to toggle party chat on.
*/
@@ -120,6 +130,8 @@ public final class ChatAPI {
/**
* Toggle the party chat mode of a player.
* </br>
* This function is designed for API usage.
*
* @param playerName The name of the player to toggle party chat on.
*/
@@ -129,6 +141,8 @@ public final class ChatAPI {
/**
* Toggle the admin chat mode of a player.
* </br>
* This function is designed for API usage.
*
* @param player The player to toggle admin chat on.
*/
@@ -138,6 +152,8 @@ public final class ChatAPI {
/**
* Toggle the admin chat mode of a player.
* </br>
* This function is designed for API usage.
*
* @param playerName The name of the player to toggle party chat on.
*/

View File

@@ -1,15 +1,20 @@
package com.gmail.nossr50.api;
import java.util.Set;
import java.util.UUID;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.api.exceptions.InvalidFormulaTypeException;
import com.gmail.nossr50.api.exceptions.InvalidPlayerException;
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
import com.gmail.nossr50.api.exceptions.InvalidXPGainReasonException;
import com.gmail.nossr50.api.exceptions.McMMOPlayerNotFoundException;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.FormulaType;
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.datatypes.skills.XPGainReason;
@@ -83,9 +88,40 @@ public final class ExperienceAPI {
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addRawXP(Player player, String skillType, float XP, String xpGainReason) {
UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
addRawXP(player, skillType, XP, xpGainReason, false);
}
/**
* Adds raw XP to the player.
* </br>
* This function is designed for API usage.
*
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
* @param xpGainReason The reason to gain XP
* @param isUnshared true if the XP cannot be shared with party members
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addRawXP(Player player, String skillType, float XP, String xpGainReason, boolean isUnshared) {
if (isUnshared) {
getPlayer(player).beginUnsharedXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
return;
}
getPlayer(player).applyXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
}
/**
* Adds raw XP to an offline player.
* </br>
* This function is designed for API usage.
*
* @deprecated We're using float for our XP values now
* replaced by {@link #addRawXPOffline(String playerName, String skillType, float XP)}
*/
@Deprecated
public static void addRawXPOffline(String playerName, String skillType, int XP) {
addRawXPOffline(playerName, skillType, (float) XP);
@@ -96,6 +132,9 @@ public final class ExperienceAPI {
* </br>
* This function is designed for API usage.
*
* @deprecated We're using uuids to get an offline player
* replaced by {@link #addRawXPOffline(UUID uuid, String skillType, float XP)}
*
* @param playerName The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
@@ -103,10 +142,27 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static void addRawXPOffline(String playerName, String skillType, float XP) {
addOfflineXP(playerName, getSkillType(skillType), (int) Math.floor(XP));
}
/**
* Adds raw XP to an offline player.
* </br>
* This function is designed for API usage.
*
* @param uuid The UUID of 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
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addRawXPOffline(UUID uuid, String skillType, float XP) {
addOfflineXP(uuid, getSkillType(skillType), (int) Math.floor(XP));
}
/**
* Adds XP to the player, calculates for XP Rate only.
* </br>
@@ -137,7 +193,7 @@ public final class ExperienceAPI {
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addMultipliedXP(Player player, String skillType, int XP, String xpGainReason) {
UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), (int) (XP * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
getPlayer(player).applyXpGain(getSkillType(skillType), (int) (XP * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
}
/**
@@ -152,6 +208,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static void addMultipliedXPOffline(String playerName, String skillType, int XP) {
addOfflineXP(playerName, getSkillType(skillType), (int) (XP * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
}
@@ -186,9 +243,32 @@ public final class ExperienceAPI {
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addModifiedXP(Player player, String skillType, int XP, String xpGainReason) {
addModifiedXP(player, skillType, XP, xpGainReason, false);
}
/**
* Adds XP to the player, calculates for XP Rate and skill modifier.
* </br>
* This function is designed for API usage.
*
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
* @param xpGainReason The reason to gain XP
* @param isUnshared true if the XP cannot be shared with party members
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addModifiedXP(Player player, String skillType, int XP, String xpGainReason, boolean isUnshared) {
SkillType skill = getSkillType(skillType);
UserManager.getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
if (isUnshared) {
getPlayer(player).beginUnsharedXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
return;
}
getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
}
/**
@@ -203,6 +283,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static void addModifiedXPOffline(String playerName, String skillType, int XP) {
SkillType skill = getSkillType(skillType);
@@ -241,7 +322,31 @@ public final class ExperienceAPI {
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addXP(Player player, String skillType, int XP, String xpGainReason) {
UserManager.getPlayer(player).beginXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
addXP(player, skillType, XP, xpGainReason, false);
}
/**
* Adds XP to the player, calculates for XP Rate, skill modifiers, perks, child skills,
* and party sharing.
* </br>
* This function is designed for API usage.
*
* @param player The player to add XP to
* @param skillType The skill to add XP to
* @param XP The amount of XP to add
* @param xpGainReason The reason to gain XP
* @param isUnshared true if the XP cannot be shared with party members
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidXPGainReasonException if the given xpGainReason is not valid
*/
public static void addXP(Player player, String skillType, int XP, String xpGainReason, boolean isUnshared) {
if (isUnshared) {
getPlayer(player).beginUnsharedXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
return;
}
getPlayer(player).beginXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
}
/**
@@ -257,7 +362,7 @@ public final class ExperienceAPI {
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXP(Player player, String skillType) {
return UserManager.getPlayer(player).getSkillXpLevel(getNonChildSkillType(skillType));
return getPlayer(player).getSkillXpLevel(getNonChildSkillType(skillType));
}
/**
@@ -273,10 +378,28 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static int getOfflineXP(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillXpLevel(getNonChildSkillType(skillType));
}
/**
* Get the amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXP(UUID uuid, String skillType) {
return getOfflineProfile(uuid).getSkillXpLevel(getNonChildSkillType(skillType));
}
/**
* Get the raw amount of XP a player has in a specific skill.
* </br>
@@ -290,7 +413,7 @@ public final class ExperienceAPI {
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getXPRaw(Player player, String skillType) {
return UserManager.getPlayer(player).getSkillXpLevelRaw(getNonChildSkillType(skillType));
return getPlayer(player).getSkillXpLevelRaw(getNonChildSkillType(skillType));
}
/**
@@ -306,10 +429,28 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static float getOfflineXPRaw(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillXpLevelRaw(getNonChildSkillType(skillType));
}
/**
* Get the raw amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getOfflineXPRaw(UUID uuid, String skillType) {
return getOfflineProfile(uuid).getSkillXpLevelRaw(getNonChildSkillType(skillType));
}
/**
* Get the total amount of XP needed to reach the next level.
* </br>
@@ -323,7 +464,7 @@ public final class ExperienceAPI {
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getXPToNextLevel(Player player, String skillType) {
return UserManager.getPlayer(player).getXpToLevel(getNonChildSkillType(skillType));
return getPlayer(player).getXpToLevel(getNonChildSkillType(skillType));
}
/**
@@ -339,10 +480,28 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static int getOfflineXPToNextLevel(String playerName, String skillType) {
return getOfflineProfile(playerName).getXpToLevel(getNonChildSkillType(skillType));
}
/**
* Get the total amount of XP an offline player needs to reach the next level.
* </br>
* This function is designed for API usage.
*
* @param uuid The player to get XP for
* @param skillType The skill to get XP for
* @return the total amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXPToNextLevel(UUID uuid, String skillType) {
return getOfflineProfile(uuid).getXpToLevel(getNonChildSkillType(skillType));
}
/**
* Get the amount of XP remaining until the next level.
* </br>
@@ -358,7 +517,7 @@ public final class ExperienceAPI {
public static int getXPRemaining(Player player, String skillType) {
SkillType skill = getNonChildSkillType(skillType);
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
PlayerProfile profile = getPlayer(player).getProfile();
return profile.getXpToLevel(skill) - profile.getSkillXpLevel(skill);
}
@@ -376,14 +535,34 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static int getOfflineXPRemaining(String playerName, String skillType) {
SkillType skill = getNonChildSkillType(skillType);
PlayerProfile profile = getOfflineProfile(playerName);
return profile.getXpToLevel(skill) - profile.getSkillXpLevel(skill);
}
/**
* Get the amount of XP an offline player has left before leveling up.
* </br>
* This function is designed for API usage.
*
* @param uuid The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getOfflineXPRemaining(UUID uuid, String skillType) {
SkillType skill = getNonChildSkillType(skillType);
PlayerProfile profile = getOfflineProfile(uuid);
return profile.getXpToLevel(skill) - profile.getSkillXpLevelRaw(skill);
}
/**
* Add levels to a skill.
* </br>
@@ -396,7 +575,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static void addLevel(Player player, String skillType, int levels) {
UserManager.getPlayer(player).addLevels(getSkillType(skillType), levels);
getPlayer(player).addLevels(getSkillType(skillType), levels);
}
/**
@@ -411,6 +590,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static void addLevelOffline(String playerName, String skillType, int levels) {
PlayerProfile profile = getOfflineProfile(playerName);
SkillType skill = getSkillType(skillType);
@@ -430,6 +610,37 @@ public final class ExperienceAPI {
profile.scheduleAsyncSave();
}
/**
* Add levels to a skill for an offline player.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void addLevelOffline(UUID uuid, String skillType, int levels) {
PlayerProfile profile = getOfflineProfile(uuid);
SkillType skill = getSkillType(skillType);
if (skill.isChildSkill()) {
Set<SkillType> parentSkills = FamilyTree.getParents(skill);
for (SkillType parentSkill : parentSkills) {
profile.addLevels(parentSkill, (levels / parentSkills.size()));
}
profile.scheduleAsyncSave();
return;
}
profile.addLevels(skill, levels);
profile.scheduleAsyncSave();
}
/**
* Get the level a player has in a specific skill.
* </br>
@@ -442,7 +653,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevel(Player player, String skillType) {
return UserManager.getPlayer(player).getSkillLevel(getSkillType(skillType));
return getPlayer(player).getSkillLevel(getSkillType(skillType));
}
/**
@@ -457,10 +668,27 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static int getLevelOffline(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillLevel(getSkillType(skillType));
}
/**
* Get the level an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param uuid 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(UUID uuid, String skillType) {
return getOfflineProfile(uuid).getSkillLevel(getSkillType(skillType));
}
/**
* Gets the power level of a player.
* </br>
@@ -470,7 +698,7 @@ public final class ExperienceAPI {
* @return the power level of the player
*/
public static int getPowerLevel(Player player) {
return UserManager.getPlayer(player).getPowerLevel();
return getPlayer(player).getPowerLevel();
}
/**
@@ -483,6 +711,7 @@ public final class ExperienceAPI {
*
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static int getPowerLevelOffline(String playerName) {
int powerLevel = 0;
PlayerProfile profile = getOfflineProfile(playerName);
@@ -494,6 +723,27 @@ public final class ExperienceAPI {
return powerLevel;
}
/**
* Gets the power level of an offline player.
* </br>
* This function is designed for API usage.
*
* @param uuid 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(UUID uuid) {
int powerLevel = 0;
PlayerProfile profile = getOfflineProfile(uuid);
for (SkillType type : SkillType.NON_CHILD_SKILLS) {
powerLevel += profile.getSkillLevel(type);
}
return powerLevel;
}
/**
* Get the level cap of a specific skill.
* </br>
@@ -533,10 +783,28 @@ public final class ExperienceAPI {
*
* @return the position on the leaderboard
*/
@Deprecated
public static int getPlayerRankSkill(String playerName, String skillType) {
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(playerName).getPlayerName()).get(getNonChildSkillType(skillType));
}
/**
* Get the position on the leaderboard of a player.
* </br>
* This function is designed for API usage.
*
* @param uuid The name of the player to check
* @param skillType The skill to check
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*
* @return the position on the leaderboard
*/
public static int getPlayerRankSkill(UUID uuid, String skillType) {
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(uuid).getPlayerName()).get(getNonChildSkillType(skillType));
}
/**
* Get the position on the power level leaderboard of a player.
@@ -549,10 +817,26 @@ public final class ExperienceAPI {
*
* @return the position on the power level leaderboard
*/
@Deprecated
public static int getPlayerRankOverall(String playerName) {
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(playerName).getPlayerName()).get(null);
}
/**
* Get the position on the power level leaderboard of a player.
* </br>
* This function is designed for API usage.
*
* @param uuid The name of the player to check
*
* @throws InvalidPlayerException if the given player does not exist in the database
*
* @return the position on the power level leaderboard
*/
public static int getPlayerRankOverall(UUID uuid) {
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(uuid).getPlayerName()).get(null);
}
/**
* Sets the level of a player in a specific skill type.
* </br>
@@ -565,7 +849,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static void setLevel(Player player, String skillType, int skillLevel) {
UserManager.getPlayer(player).modifySkill(getSkillType(skillType), skillLevel);
getPlayer(player).modifySkill(getSkillType(skillType), skillLevel);
}
/**
@@ -580,10 +864,27 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static void setLevelOffline(String playerName, String skillType, int skillLevel) {
getOfflineProfile(playerName).modifySkill(getSkillType(skillType), skillLevel);
}
/**
* Sets the level of an offline player in a specific skill type.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static void setLevelOffline(UUID uuid, String skillType, int skillLevel) {
getOfflineProfile(uuid).modifySkill(getSkillType(skillType), skillLevel);
}
/**
* Sets the XP of a player in a specific skill type.
* </br>
@@ -597,7 +898,7 @@ public final class ExperienceAPI {
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void setXP(Player player, String skillType, int newValue) {
UserManager.getPlayer(player).setSkillXpLevel(getNonChildSkillType(skillType), newValue);
getPlayer(player).setSkillXpLevel(getNonChildSkillType(skillType), newValue);
}
/**
@@ -613,10 +914,28 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static void setXPOffline(String playerName, String skillType, int newValue) {
getOfflineProfile(playerName).setSkillXpLevel(getNonChildSkillType(skillType), newValue);
}
/**
* Sets the XP of an offline player in a specific skill type.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void setXPOffline(UUID uuid, String skillType, int newValue) {
getOfflineProfile(uuid).setSkillXpLevel(getNonChildSkillType(skillType), newValue);
}
/**
* Removes XP from a player in a specific skill type.
* </br>
@@ -630,7 +949,7 @@ public final class ExperienceAPI {
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void removeXP(Player player, String skillType, int xp) {
UserManager.getPlayer(player).removeXp(getNonChildSkillType(skillType), xp);
getPlayer(player).removeXp(getNonChildSkillType(skillType), xp);
}
/**
@@ -646,12 +965,64 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
@Deprecated
public static void removeXPOffline(String playerName, String skillType, int xp) {
getOfflineProfile(playerName).removeXp(getNonChildSkillType(skillType), xp);
}
// Utility methods follow.
/**
* Removes XP from an offline player in a specific skill type.
* </br>
* This function is designed for API usage.
*
* @param uuid 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
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static void removeXPOffline(UUID uuid, String skillType, int xp) {
getOfflineProfile(uuid).removeXp(getNonChildSkillType(skillType), xp);
}
/**
* Check how much XP is needed for a specific level with the selected level curve.
* </br>
* This function is designed for API usage.
*
* @param level The level to get the amount of XP for
*
* @throws InvalidFormulaTypeException if the given formulaType is not valid
*/
public static int getXpNeededToLevel(int level) {
return mcMMO.getFormulaManager().getCachedXpToLevel(level, ExperienceConfig.getInstance().getFormulaType());
}
/**
* Check how much XP is needed for a specific level with the provided level curve.
* </br>
* This function is designed for API usage.
*
* @param level The level to get the amount of XP for
* @param formulaType The formula type to get the amount of XP for
*
* @throws InvalidFormulaTypeException if the given formulaType is not valid
*/
public static int getXpNeededToLevel(int level, String formulaType) {
return mcMMO.getFormulaManager().getCachedXpToLevel(level, getFormulaType(formulaType));
}
// Utility methods follow.
private static void addOfflineXP(UUID playerUniqueId, SkillType skill, int XP) {
PlayerProfile profile = getOfflineProfile(playerUniqueId);
profile.addXp(skill, XP);
profile.save();
}
@Deprecated
private static void addOfflineXP(String playerName, SkillType skill, int XP) {
PlayerProfile profile = getOfflineProfile(playerName);
@@ -659,8 +1030,20 @@ public final class ExperienceAPI {
profile.scheduleAsyncSave();
}
private static PlayerProfile getOfflineProfile(UUID uuid) {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
if (!profile.isLoaded()) {
throw new InvalidPlayerException();
}
return profile;
}
@Deprecated
private static PlayerProfile getOfflineProfile(String playerName) {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false);
UUID uuid = mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId();
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
if (!profile.isLoaded()) {
throw new InvalidPlayerException();
@@ -698,4 +1081,22 @@ public final class ExperienceAPI {
return xpGainReason;
}
private static FormulaType getFormulaType(String formula) throws InvalidFormulaTypeException {
FormulaType formulaType = FormulaType.getFormulaType(formula);
if (formulaType == null) {
throw new InvalidFormulaTypeException();
}
return formulaType;
}
private static McMMOPlayer getPlayer(Player player) throws McMMOPlayerNotFoundException {
if (!UserManager.hasPlayerDataKey(player)) {
throw new McMMOPlayerNotFoundException(player);
}
return UserManager.getPlayer(player);
}
}

View File

@@ -1,14 +1,17 @@
package com.gmail.nossr50.api;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.UUID;
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.datatypes.party.PartyLeader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.UserManager;
@@ -79,7 +82,7 @@ public final class PartyAPI {
Party party = PartyManager.getParty(partyName);
if (party == null) {
party = new Party(player.getName(), partyName);
party = new Party(new PartyLeader(player.getUniqueId(), player.getName()), partyName);
}
PartyManager.addToParty(UserManager.getPlayer(player), party);
@@ -105,7 +108,7 @@ public final class PartyAPI {
* @return the leader of the party
*/
public static String getPartyLeader(String partyName) {
return PartyManager.getPartyLeader(partyName);
return PartyManager.getPartyLeaderName(partyName);
}
/**
@@ -114,10 +117,11 @@ public final class PartyAPI {
* This function is designed for API usage.
*
* @param partyName The name of the party to set the leader of
* @param player The player to set as leader
* @param playerName The playerName to set as leader
*/
public static void setPartyLeader(String partyName, String player) {
PartyManager.setPartyLeader(player, PartyManager.getParty(partyName));
@Deprecated
public static void setPartyLeader(String partyName, String playerName) {
PartyManager.setPartyLeader(mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId(), PartyManager.getParty(partyName));
}
/**
@@ -132,8 +136,8 @@ public final class PartyAPI {
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);
for (UUID memberUniqueId : PartyManager.getAllMembers(player).keySet()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberUniqueId);
members.add(member);
}
return members;
@@ -147,7 +151,20 @@ public final class PartyAPI {
* @param player The player to check
* @return all the player names in the player's party
*/
@Deprecated
public static LinkedHashSet<String> getMembers(Player player) {
return (LinkedHashSet<String>) PartyManager.getAllMembers(player).values();
}
/**
* Get a list of all player names and uuids in this player's party.
* </br>
* This function is designed for API usage.
*
* @param player The player to check
* @return all the player names and uuids in the player's party
*/
public static LinkedHashMap<UUID, String> getMembersMap(Player player) {
return PartyManager.getAllMembers(player);
}
@@ -175,6 +192,14 @@ public final class PartyAPI {
return PartyManager.getOnlineMembers(player);
}
/**
* Check is a certain party has an ally
* </br>
* This function is designed for API usage.
*
* @param partyName The name of the party to check
* @return true if the party has an ally, false otherwise
*/
public static boolean hasAlly(String partyName) {
return getAllyName(partyName) != null;
}

View File

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

View File

@@ -0,0 +1,11 @@
package com.gmail.nossr50.api.exceptions;
import org.bukkit.entity.Player;
public class McMMOPlayerNotFoundException extends RuntimeException {
private static final long serialVersionUID = 761917904993202836L;
public McMMOPlayerNotFoundException(Player player) {
super("McMMOPlayer object was not found for: " + player.getName() + " " + player.getUniqueId());
}
}

View File

@@ -29,6 +29,10 @@ public class KrakenCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
UserManager.getPlayer(sender.getName()).getFishingManager().unleashTheKraken();
return true;

View File

@@ -0,0 +1,351 @@
package com.gmail.nossr50.commands;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import org.bukkit.Material;
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.skills.ModConfigType;
import com.gmail.nossr50.util.Misc;
public class McImportCommand implements CommandExecutor {
int fileAmount;
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) {
case 0:
importModConfig();
return true;
default:
return false;
}
}
public boolean importModConfig() {
String importFilePath = mcMMO.getModDirectory() + File.separator + "import";
File importFile = new File(importFilePath, "import.log");
mcMMO.p.getLogger().info("Starting import of mod materials...");
fileAmount = 0;
HashMap<ModConfigType, ArrayList<String>> materialNames = new HashMap<ModConfigType, ArrayList<String>>();
BufferedReader in = null;
try {
// Open the file
in = new BufferedReader(new FileReader(importFile));
String line;
String materialName;
String modName;
// While not at the end of the file
while ((line = in.readLine()) != null) {
String[] split1 = line.split("material ");
if (split1.length != 2) {
continue;
}
String[] split2 = split1[1].split(" with");
if (split2.length != 2) {
continue;
}
materialName = split2[0];
// Categorise each material under a mod config type
ModConfigType type = ModConfigType.getModConfigType(materialName);
if (!materialNames.containsKey(type)) {
materialNames.put(type, new ArrayList<String>());
}
materialNames.get(type).add(materialName);
continue;
}
}
catch (FileNotFoundException e) {
mcMMO.p.getLogger().warning("Could not find " + importFile.getAbsolutePath() + " ! (No such file or directory)");
mcMMO.p.getLogger().warning("Copy and paste latest.log to " + importFile.getParentFile().getAbsolutePath() + " and rename it to import.log");
return false;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
finally {
tryClose(in);
}
createOutput(materialNames);
mcMMO.p.getLogger().info("Import finished! Created " + fileAmount + " files!");
return true;
}
private void createOutput(HashMap<ModConfigType, ArrayList<String>> materialNames) {
for (ModConfigType modConfigType : materialNames.keySet()) {
HashMap<String, ArrayList<String>> materialNamesType = new HashMap<String, ArrayList<String>>();
for (String materialName : materialNames.get(modConfigType)) {
String modName = Misc.getModName(materialName);
if (!materialNamesType.containsKey(modName)) {
materialNamesType.put(modName, new ArrayList<String>());
}
materialNamesType.get(modName).add(materialName);
}
createOutput(modConfigType, materialNamesType);
}
}
private void tryClose(Closeable c) {
if (c == null) {
return;
}
try {
c.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private void createOutput(ModConfigType modConfigType, HashMap<String, ArrayList<String>> materialNames) {
File outputFilePath = new File(mcMMO.getModDirectory() + File.separator + "output");
if (!outputFilePath.exists() && !outputFilePath.mkdirs()) {
mcMMO.p.getLogger().severe("Could not create output directory! " + outputFilePath.getAbsolutePath());
}
FileWriter out = null;
String type = modConfigType.name().toLowerCase();
for (String modName : materialNames.keySet()) {
File outputFile = new File(outputFilePath, modName + "." + type + ".yml");
mcMMO.p.getLogger().info("Creating " + outputFile.getName());
try {
if (outputFile.exists() && !outputFile.delete()) {
mcMMO.p.getLogger().severe("Not able to delete old output file! " + outputFile.getAbsolutePath());
}
if (!outputFile.createNewFile()) {
mcMMO.p.getLogger().severe("Could not create output file! " + outputFile.getAbsolutePath());
continue;
}
StringBuilder writer = new StringBuilder();
HashMap<String, ArrayList<String>> configSections = getConfigSections(modConfigType, modName, materialNames);
if (configSections == null) {
mcMMO.p.getLogger().severe("Something went wrong!! type is " + type);
return;
}
// Write the file, go through each skill and write all the materials
for (String configSection : configSections.keySet()) {
if (configSection.equals("UNIDENTIFIED")) {
writer.append("# This isn't a valid config section and all materials in this category need to be").append("\r\n");
writer.append("# copy and pasted to a valid section of this config file.").append("\r\n");
}
writer.append(configSection).append(":").append("\r\n");
for (String line : configSections.get(configSection)) {
writer.append(line).append("\r\n");
}
writer.append("\r\n");
}
out = new FileWriter(outputFile);
out.write(writer.toString());
}
catch (IOException e) {
e.printStackTrace();
return;
}
catch (Exception e) {
e.printStackTrace();
return;
}
finally {
tryClose(out);
fileAmount++;
}
}
}
private HashMap<String, ArrayList<String>> getConfigSections(ModConfigType type, String modName, HashMap<String, ArrayList<String>> materialNames) {
switch (type) {
case BLOCKS:
return getConfigSectionsBlocks(modName, materialNames);
case TOOLS:
return getConfigSectionsTools(modName, materialNames);
case ARMOR:
return getConfigSectionsArmor(modName, materialNames);
case UNKNOWN:
return getConfigSectionsUnknown(modName, materialNames);
}
return null;
}
private HashMap<String, ArrayList<String>> getConfigSectionsBlocks(String modName, HashMap<String, ArrayList<String>> materialNames) {
HashMap<String, ArrayList<String>> configSections = new HashMap<String, ArrayList<String>>();
// Go through all the materials and categorise them under a skill
for (String materialName : materialNames.get(modName)) {
String skillName = "UNIDENTIFIED";
if (materialName.contains("ORE")) {
skillName = "Mining";
}
else if (materialName.contains("LOG") || materialName.contains("LEAVES")) {
skillName = "Woodcutting";
}
else if (materialName.contains("GRASS") || materialName.contains("FLOWER") || materialName.contains("CROP")) {
skillName = "Herbalism";
}
else if (materialName.contains("DIRT") || materialName.contains("SAND")) {
skillName = "Excavation";
}
if (!configSections.containsKey(skillName)) {
configSections.put(skillName, new ArrayList<String>());
}
ArrayList<String> skillContents = configSections.get(skillName);
skillContents.add(" " + materialName + "|0:");
skillContents.add(" " + " " + "XP_Gain: 99");
skillContents.add(" " + " " + "Double_Drops_Enabled: true");
if (skillName.equals("Mining")) {
skillContents.add(" " + " " + "Smelting_XP_Gain: 9");
}
else if (skillName.equals("Woodcutting")) {
skillContents.add(" " + " " + "Is_Log: " + materialName.contains("LOG"));
}
}
return configSections;
}
private HashMap<String, ArrayList<String>> getConfigSectionsTools(String modName, HashMap<String, ArrayList<String>> materialNames) {
HashMap<String, ArrayList<String>> configSections = new HashMap<String, ArrayList<String>>();
// Go through all the materials and categorise them under a tool type
for (String materialName : materialNames.get(modName)) {
String toolType = "UNIDENTIFIED";
if (materialName.contains("PICKAXE")) {
toolType = "Pickaxes";
}
else if (materialName.contains("AXE")) {
toolType = "Axes";
}
else if (materialName.contains("BOW")) {
toolType = "Bows";
}
else if (materialName.contains("HOE")) {
toolType = "Hoes";
}
else if (materialName.contains("SHOVEL") || materialName.contains("SPADE")) {
toolType = "Shovels";
}
else if (materialName.contains("SWORD")) {
toolType = "Swords";
}
if (!configSections.containsKey(toolType)) {
configSections.put(toolType, new ArrayList<String>());
}
ArrayList<String> skillContents = configSections.get(toolType);
skillContents.add(" " + materialName + ":");
skillContents.add(" " + " " + "XP_Modifier: 1.0");
skillContents.add(" " + " " + "Tier: 1");
skillContents.add(" " + " " + "Ability_Enabled: true");
addRepairableLines(materialName, skillContents);
}
return configSections;
}
private HashMap<String, ArrayList<String>> getConfigSectionsArmor(String modName, HashMap<String, ArrayList<String>> materialNames) {
HashMap<String, ArrayList<String>> configSections = new HashMap<String, ArrayList<String>>();
// Go through all the materials and categorise them under an armor type
for (String materialName : materialNames.get(modName)) {
String toolType = "UNIDENTIFIED";
if (materialName.contains("BOOT") || materialName.contains("SHOE")) {
toolType = "Boots";
}
else if (materialName.contains("CHESTPLATE") || materialName.contains("CHEST")) {
toolType = "Chestplates";
}
else if (materialName.contains("HELM") || materialName.contains("HAT")) {
toolType = "Helmets";
}
else if (materialName.contains("LEGGINGS") || materialName.contains("LEGS") || materialName.contains("PANTS")) {
toolType = "Leggings";
}
if (!configSections.containsKey(toolType)) {
configSections.put(toolType, new ArrayList<String>());
}
ArrayList<String> skillContents = configSections.get(toolType);
skillContents.add(" " + materialName + ":");
addRepairableLines(materialName, skillContents);
}
return configSections;
}
private void addRepairableLines(String materialName, ArrayList<String> skillContents) {
skillContents.add(" " + " " + "Repairable: true");
skillContents.add(" " + " " + "Repair_Material: REPAIR_MATERIAL_NAME");
skillContents.add(" " + " " + "Repair_Material_Data_Value: 0");
skillContents.add(" " + " " + "Repair_Material_Quantity: 9");
skillContents.add(" " + " " + "Repair_Material_Pretty_Name: Repair Item Name");
skillContents.add(" " + " " + "Repair_MinimumLevel: 0");
skillContents.add(" " + " " + "Repair_XpMultiplier: 1.0");
Material material = Material.matchMaterial(materialName);
short durability = (material == null) ? (short) 9999 : material.getMaxDurability();
skillContents.add(" " + " " + "Durability: " + ((durability > 0) ? durability : (short) 9999));
}
private HashMap<String, ArrayList<String>> getConfigSectionsUnknown(String modName, HashMap<String, ArrayList<String>> materialNames) {
HashMap<String, ArrayList<String>> configSections = new HashMap<String, ArrayList<String>>();
// Go through all the materials and print them
for (String materialName : materialNames.get(modName)) {
String configKey = "UNIDENTIFIED";
if (!configSections.containsKey(configKey)) {
configSections.put(configKey, new ArrayList<String>());
}
ArrayList<String> skillContents = configSections.get(configKey);
skillContents.add(" " + materialName);
}
return configSections;
}
}

View File

@@ -27,7 +27,7 @@ public class McmmoCommand implements CommandExecutor {
if (Config.getInstance().getDonateMessageEnabled()) {
sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "gjmcferrin@gmail.com" + ChatColor.GOLD + " Paypal");
sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "tft_02@hotmail.com" + ChatColor.GOLD + " Paypal");
}
if (Permissions.showversion(sender)) {

View File

@@ -37,6 +37,10 @@ public class MobhealthCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
switch (args.length) {
case 1:
try {

View File

@@ -28,6 +28,10 @@ public abstract class ToggleCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
applyCommandAction(UserManager.getPlayer(sender.getName()));
return true;

View File

@@ -41,6 +41,10 @@ public abstract class ChatCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
mcMMOPlayer = UserManager.getPlayer(sender.getName());
if (mcMMOPlayer.isChatEnabled(chatMode)) {
@@ -53,6 +57,10 @@ public abstract class ChatCommand implements TabExecutor {
return true;
case 1:
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
if (CommandUtils.shouldEnableToggle(args[0])) {
if (CommandUtils.noConsoleUsage(sender)) {
return true;

View File

@@ -12,6 +12,7 @@ import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.database.DatabaseConversionTask;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
import com.gmail.nossr50.util.player.UserManager;
public class ConvertDatabaseCommand implements CommandExecutor {
@@ -55,13 +56,13 @@ public class ConvertDatabaseCommand implements CommandExecutor {
UserManager.clearAll();
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getName(), false);
PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getUniqueId());
if (profile.isLoaded()) {
mcMMO.getDatabaseManager().saveUser(profile);
}
UserManager.addUser(player);
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
}
new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()).runTaskAsynchronously(mcMMO.p);

View File

@@ -9,6 +9,7 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.database.FormulaConversionTask;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
import com.gmail.nossr50.util.player.UserManager;
public class ConvertExperienceCommand implements CommandExecutor {
@@ -37,7 +38,7 @@ public class ConvertExperienceCommand implements CommandExecutor {
new FormulaConversionTask(sender, newType).runTaskLater(mcMMO.p, 1);
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
UserManager.addUser(player);
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
}
return true;

View File

@@ -1,10 +1,12 @@
package com.gmail.nossr50.commands.party;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
@@ -18,13 +20,14 @@ public class PartyChangeOwnerCommand implements CommandExecutor {
case 2:
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
String targetName = CommandUtils.getMatchedPlayerName(args[1]);
OfflinePlayer target = mcMMO.p.getServer().getOfflinePlayer(targetName);
if (!playerParty.getMembers().contains(targetName)) {
if (!playerParty.hasMember(target.getUniqueId())) {
sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
return true;
}
PartyManager.setPartyLeader(targetName, playerParty);
PartyManager.setPartyLeader(target.getUniqueId(), playerParty);
return true;
default:

View File

@@ -71,6 +71,11 @@ public class PartyCommand implements TabExecutor {
}
Player player = (Player) sender;
if (!UserManager.hasPlayerDataKey(player)) {
return true;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (args.length < 1) {
@@ -129,7 +134,7 @@ public class PartyCommand implements TabExecutor {
}
// Party leader commands
if (!mcMMOPlayer.getParty().getLeader().equalsIgnoreCase(player.getName())) {
if (!mcMMOPlayer.getParty().getLeader().getUniqueId().equals(player.getUniqueId())) {
sender.sendMessage(LocaleLoader.getString("Party.NotOwner"));
return true;
}

View File

@@ -22,7 +22,7 @@ public class PartyKickCommand implements CommandExecutor {
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
String targetName = CommandUtils.getMatchedPlayerName(args[1]);
if (!playerParty.getMembers().contains(targetName)) {
if (!playerParty.hasMember(targetName)) {
sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
return true;
}

View File

@@ -36,7 +36,7 @@ public class PartyRenameCommand implements CommandExecutor {
return true;
}
String leaderName = playerParty.getLeader();
String leaderName = playerParty.getLeader().getPlayerName();
for (Player member : playerParty.getOnlineMembers()) {
if (!PartyManager.handlePartyChangeEvent(member, oldPartyName, newPartyName, EventReason.CHANGED_PARTIES)) {

View File

@@ -44,7 +44,7 @@ public class PartyAllianceInviteCommand implements CommandExecutor {
return true;
}
if (!mcMMOTarget.getParty().getLeader().equalsIgnoreCase(targetName)) {
if (!mcMMOTarget.getParty().getLeader().getUniqueId().equals(target.getUniqueId())) {
player.sendMessage(LocaleLoader.getString("Party.Target.NotOwner", targetName));
return true;
}

View File

@@ -42,6 +42,11 @@ public class PtpCommand implements TabExecutor {
}
Player player = (Player) sender;
if (!UserManager.hasPlayerDataKey(player)) {
return true;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (!mcMMOPlayer.inParty()) {

View File

@@ -34,6 +34,10 @@ public class InspectCommand implements TabExecutor {
if (mcMMOPlayer == null) {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false); // Temporary Profile
if (!CommandUtils.isLoaded(sender, profile)) {
return true;
}
if (CommandUtils.inspectOffline(sender, profile, Permissions.inspectOffline(sender))) {
return true;
}

View File

@@ -24,6 +24,10 @@ public class MccooldownCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
switch (args.length) {
case 0:
Player player = (Player) sender;

View File

@@ -7,6 +7,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
@@ -34,6 +35,10 @@ public class McrankCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
display(sender, sender.getName());
return true;
@@ -44,6 +49,10 @@ public class McrankCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
String playerName = CommandUtils.getMatchedPlayerName(args[0]);
McMMOPlayer mcMMOPlayer = UserManager.getOfflinePlayer(playerName);
@@ -88,6 +97,13 @@ public class McrankCommand implements TabExecutor {
return;
}
if (((Player) sender).hasMetadata(mcMMO.databaseCommandKey)) {
sender.sendMessage(LocaleLoader.getString("Commands.Database.Processing"));
return;
} else {
((Player) sender).setMetadata(mcMMO.databaseCommandKey, new FixedMetadataValue(mcMMO.p, null));
}
mcMMOPlayer.actualizeDatabaseATS();
}

View File

@@ -22,6 +22,10 @@ public class McstatsCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
switch (args.length) {
case 0:
Player player = (Player) sender;

View File

@@ -7,6 +7,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO;
@@ -19,7 +20,6 @@ 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.google.common.collect.ImmutableList;
public class MctopCommand implements TabExecutor {
@@ -83,6 +83,10 @@ public class MctopCommand implements TabExecutor {
}
if (sender instanceof Player) {
if (!CommandUtils.hasPlayerDataKey(sender)) {
return;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
long cooldownMillis = Math.max(Config.getInstance().getDatabasePlayerCooldown(), 1750);
@@ -91,6 +95,13 @@ public class MctopCommand implements TabExecutor {
return;
}
if (((Player) sender).hasMetadata(mcMMO.databaseCommandKey)) {
sender.sendMessage(LocaleLoader.getString("Commands.Database.Processing"));
return;
} else {
((Player) sender).setMetadata(mcMMO.databaseCommandKey, new FixedMetadataValue(mcMMO.p, null));
}
mcMMOPlayer.actualizeDatabaseATS();
}

View File

@@ -48,6 +48,10 @@ public abstract class SkillCommand implements TabExecutor {
return true;
}
if (!CommandUtils.hasPlayerDataKey(sender)) {
return true;
}
switch (args.length) {
case 0:
Player player = (Player) sender;

View File

@@ -12,6 +12,7 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.taming.Taming;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
public class TamingCommand extends SkillCommand {
private String goreChance;
@@ -91,9 +92,13 @@ public class TamingCommand extends SkillCommand {
if (canCallWild) {
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Taming.Effect.12"), LocaleLoader.getString("Taming.Effect.13")));
messages.add(LocaleLoader.getString("Taming.Effect.14", Config.getInstance().getTamingCOTWCost(EntityType.OCELOT)));
messages.add(LocaleLoader.getString("Taming.Effect.15", Config.getInstance().getTamingCOTWCost(EntityType.WOLF)));
messages.add(LocaleLoader.getString("Taming.Effect.20", Config.getInstance().getTamingCOTWCost(EntityType.HORSE)));
int costOcelot = Config.getInstance().getTamingCOTWCost(EntityType.OCELOT);
String itemOcelot = StringUtils.getPrettyItemString(Config.getInstance().getTamingCOTWMaterial(EntityType.OCELOT));
int costWolf = Config.getInstance().getTamingCOTWCost(EntityType.WOLF);
String itemWolf = StringUtils.getPrettyItemString(Config.getInstance().getTamingCOTWMaterial(EntityType.WOLF));
int costHorse = Config.getInstance().getTamingCOTWCost(EntityType.HORSE);
String itemHorse = StringUtils.getPrettyItemString(Config.getInstance().getTamingCOTWMaterial(EntityType.HORSE));
messages.add(LocaleLoader.getString("Taming.Effect.14", costOcelot, itemOcelot, costWolf, itemWolf, costHorse, itemHorse));
}
return messages;

View File

@@ -420,8 +420,8 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
reason.add("Skills.Salvage.MaxPercentageLevel should be at least 1!");
}
if (getAdvancedSalvageUnlockLevel() < 1) {
reason.add("Skills.Salvage.AdvancedSalvage.UnlockLevel should be at least 1!");
if (getAdvancedSalvageUnlockLevel() < 0) {
reason.add("Skills.Salvage.AdvancedSalvage.UnlockLevel should be at least 0!");
}
List<Salvage.Tier> salvageTierList = Arrays.asList(Salvage.Tier.values());
@@ -442,8 +442,8 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
if (tier != Salvage.Tier.EIGHT) {
Salvage.Tier nextTier = salvageTierList.get(salvageTierList.indexOf(tier) - 1);
if (getArcaneSalvageRankLevel(tier) >= getArcaneSalvageRankLevel(nextTier)) {
reason.add("Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + tier.toNumerical() + " should be less than Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + nextTier.toNumerical() + "!");
if (getArcaneSalvageRankLevel(tier) > getArcaneSalvageRankLevel(nextTier)) {
reason.add("Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + tier.toNumerical() + " should be less than or equal to Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + nextTier.toNumerical() + "!");
}
if (getArcaneSalvageExtractFullEnchantsChance(tier) > getArcaneSalvageExtractFullEnchantsChance(nextTier)) {

View File

@@ -9,6 +9,7 @@ import org.bukkit.TreeSpecies;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import com.gmail.nossr50.database.SQLDatabaseManager.PoolIdentifier;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.skills.AbilityType;
@@ -41,6 +42,16 @@ public class Config extends AutoUpdateConfigLoader {
reason.add("General.Save_Interval should be greater than 0!");
}
/* MySQL Settings */
for (PoolIdentifier identifier : PoolIdentifier.values()) {
if (getMySQLMaxConnections(identifier) <= 0) {
reason.add("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
}
if (getMySQLMaxPoolSize(identifier) <= 0) {
reason.add("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
}
}
/* Mob Healthbar */
if (getMobHealthbarTime() == 0) {
reason.add("Mob_Healthbar.Display_Time cannot be 0! Set to -1 to disable or set a valid value.");
@@ -232,6 +243,7 @@ public class Config extends AutoUpdateConfigLoader {
/* General Settings */
public String getLocale() { return config.getString("General.Locale", "en_us"); }
public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); }
public boolean getShowProfileLoadedMessage() { return config.getBoolean("General.Show_Profile_Loaded", true); }
public boolean getDonateMessageEnabled() { return config.getBoolean("Commands.mcmmo.Donate_Message", true); }
public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); }
public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); }
@@ -251,6 +263,7 @@ public class Config extends AutoUpdateConfigLoader {
public long getDatabasePlayerCooldown() { return config.getLong("Commands.Database.Player_Cooldown", 1750); }
public boolean getLevelUpSoundsEnabled() { return config.getBoolean("General.LevelUp_Sounds", true); }
public boolean getRefreshChunksEnabled() { return config.getBoolean("General.Refresh_Chunks", false); }
/* Mob Healthbar */
public MobHealthbarType getMobHealthbarDefault() {
@@ -269,6 +282,7 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getAllowKeepBoard() { return config.getBoolean("Scoreboard.Allow_Keep", true); }
public boolean getShowStatsAfterLogin() { return config.getBoolean("Scoreboard.Show_Stats_After_Login", false); }
public boolean getScoreboardRainbows() { return config.getBoolean("Scoreboard.Rainbows", false); }
public boolean getShowAbilityNames() { return config.getBoolean("Scoreboard.Ability_Names", true); }
public boolean getRankUseChat() { return config.getBoolean("Scoreboard.Types.Rank.Print", false); }
public boolean getRankUseBoard() { return config.getBoolean("Scoreboard.Types.Rank.Board", true); }
@@ -313,6 +327,8 @@ public class Config extends AutoUpdateConfigLoader {
public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); }
public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); }
public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); }
public int getMySQLMaxConnections(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()), 30); }
public int getMySQLMaxPoolSize(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()), 10); }
private String getStringIncludingInts(String key) {
String str = config.getString(key);
@@ -367,6 +383,7 @@ public class Config extends AutoUpdateConfigLoader {
public boolean getDodgeEffectEnabled() { return config.getBoolean("Particles.Dodge", true); }
public boolean getBleedEffectEnabled() { return config.getBoolean("Particles.Bleed", true); }
public boolean getGreaterImpactEffectEnabled() { return config.getBoolean("Particles.Greater_Impact", true); }
public boolean getCallOfTheWildEffectEnabled() { return config.getBoolean("Particles.Call_of_the_Wild", true); }
public boolean getLevelUpEffectsEnabled() { return config.getBoolean("Particles.LevelUp_Enabled", true); }
public int getLevelUpEffectsTier() { return config.getInt("Particles.LevelUp_Tier", 100); }
public boolean getLargeFireworks() { return config.getBoolean("Particles.LargeFireworks", true); }
@@ -480,6 +497,8 @@ public class Config extends AutoUpdateConfigLoader {
public Material getTamingCOTWMaterial(EntityType type) { return Material.matchMaterial(config.getString("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Material")); }
public int getTamingCOTWCost(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Amount"); }
public int getTamingCOTWAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Amount"); }
public int getTamingCOTWLength(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Length"); }
public int getTamingCOTWMaxAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Max_Amount"); }
public double getTamingCOTWRange() { return config.getDouble("Skills.Taming.Call_Of_The_Wild.Range", 40.0D); }
/* Woodcutting */

View File

@@ -6,15 +6,17 @@ import com.gmail.nossr50.mcMMO;
public class HiddenConfig {
private static HiddenConfig instance;
private static String fileName;
private static YamlConfiguration config;
private static boolean chunkletsEnabled;
private static int conversionRate;
private static boolean useEnchantmentBuffs;
private static boolean resendChunksAfterBlockAbility;
private String fileName;
private YamlConfiguration config;
private boolean chunkletsEnabled;
private int conversionRate;
private boolean useEnchantmentBuffs;
private int uuidConvertAmount;
private int mojangRateLimit;
private long mojangLimitPeriod;
public HiddenConfig(String fileName) {
HiddenConfig.fileName = fileName;
this.fileName = fileName;
load();
}
@@ -32,7 +34,9 @@ public class HiddenConfig {
chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
conversionRate = config.getInt("Options.ConversionRate", 1);
useEnchantmentBuffs = config.getBoolean("Options.EnchantmentBuffs", true);
resendChunksAfterBlockAbility = config.getBoolean("Options.RefreshChunks", false);
uuidConvertAmount = config.getInt("Options.UUIDConvertAmount", 5);
mojangRateLimit = config.getInt("Options.MojangRateLimit", 50000);
mojangLimitPeriod = config.getLong("Options.MojangLimitPeriod", 600000);
}
}
@@ -48,7 +52,15 @@ public class HiddenConfig {
return useEnchantmentBuffs;
}
public boolean resendChunksAfterBlockAbility() {
return resendChunksAfterBlockAbility;
public int getUUIDConvertAmount() {
return uuidConvertAmount;
}
public int getMojangRateLimit() {
return mojangRateLimit;
}
public long getMojangLimitPeriod() {
return mojangLimitPeriod;
}
}

View File

@@ -179,6 +179,11 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
/* Custom XP perk */
public double getCustomXpPerkBoost() { return config.getDouble("Experience_Formula.Custom_XP_Perk.Boost", 1.25); }
/* Diminished Returns */
public boolean getDiminishedReturnsEnabled() { return config.getBoolean("Diminished_Returns.Enabled", false); }
public int getDiminishedReturnsThreshold(SkillType skill) { return config.getInt("Diminished_Returns.Threshold." + StringUtils.getCapitalized(skill.toString()), 20000); }
public int getDiminishedReturnsTimeInterval() { return config.getInt("Diminished_Returns.Time_Interval", 10); }
/* Conversion */
public double getExpModifier() { return config.getDouble("Conversion.Exp_Modifier", 1); }
@@ -207,6 +212,41 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
/* Alchemy */
public double getPotionXP(PotionStage stage) { return config.getDouble("Experience.Alchemy.Potion_Stage_" + stage.toNumerical(), 10D); }
/* Excavation */
public int getDirtAndSandXp(MaterialData data) {
Material type = data.getItemType();
if (type == Material.DIRT) {
switch (data.getData()) {
case 0x0:
return config.getInt("Experience.Excavation.Dirt", 40);
case 0x1:
return config.getInt("Experience.Excavation.Coarse_Dirt", 40);
case 0x2:
return config.getInt("Experience.Excavation.Podzol", 40);
default:
return 0;
}
}
else if (type == Material.SAND) {
switch (data.getData()) {
case 0x0:
return config.getInt("Experience.Excavation.Sand", 40);
case 0x1:
return config.getInt("Experience.Excavation.Red_Sand", 40);
default:
return 0;
}
}
return 0;
}
/* Fishing */
public int getFishXp(MaterialData data) {
switch (data.getData()) {

View File

@@ -72,7 +72,7 @@ public class CustomArmorConfig extends ConfigLoader {
boolean repairable = config.getBoolean(armorType + "." + armorName + ".Repairable");
Material repairMaterial = Material.matchMaterial(config.getString(armorType + "." + armorName + ".Repair_Material", ""));
if (repairMaterial == null) {
if (repairable && (repairMaterial == null)) {
plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + armorName);
repairable = false;
}
@@ -82,7 +82,7 @@ public class CustomArmorConfig extends ConfigLoader {
int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(armorMaterial), repairMaterial, repairData);
if (repairQuantity == 0) {
repairQuantity = config.getInt(armorType + "." + armorName + ".Repair_Material_Data_Quantity", 2);
repairQuantity = config.getInt(armorType + "." + armorName + ".Repair_Material_Quantity", 2);
}
String repairItemName = config.getString(armorType + "." + armorName + ".Repair_Material_Pretty_Name");

View File

@@ -80,7 +80,7 @@ public class CustomToolConfig extends ConfigLoader {
boolean repairable = config.getBoolean(toolType + "." + toolName + ".Repairable");
Material repairMaterial = Material.matchMaterial(config.getString(toolType + "." + toolName + ".Repair_Material", ""));
if (repairMaterial == null) {
if (repairable && (repairMaterial == null)) {
plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
repairable = false;
}
@@ -90,7 +90,7 @@ public class CustomToolConfig extends ConfigLoader {
int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(toolMaterial), repairMaterial, repairData);
if (repairQuantity == 0) {
repairQuantity = config.getInt(toolType + "." + toolName + ".Repair_Material_Data_Quantity", 2);
repairQuantity = config.getInt(toolType + "." + toolName + ".Repair_Material_Quantity", 2);
}
String repairItemName = config.getString(toolType + "." + toolName + ".Repair_Material_Pretty_Name");

View File

@@ -2,6 +2,7 @@ package com.gmail.nossr50.database;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.DatabaseType;
@@ -10,8 +11,8 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
public interface DatabaseManager {
// One month in milliseconds
public final long PURGE_TIME = 2630000000L * Config.getInstance().getOldUsersCutoff();
// One month in seconds
public final long PURGE_TIME = 2630000L * Config.getInstance().getOldUsersCutoff();
// During convertUsers, how often to output a status
public final int progressInterval = 200;
@@ -54,7 +55,7 @@ public interface DatabaseManager {
/**
* Retrieve rank info into a HashMap from SkillType to the rank.
* <p>
* The special value <code>null</code> is used to represent the Power
* The special value {@code null} is used to represent the Power
* Level rank (the combination of all skill levels).
*
* @param playerName The name of the user to retrieve the rankings for
@@ -66,20 +67,44 @@ public interface DatabaseManager {
* Add a new user to the database.
*
* @param playerName The name of the player to be added to the database
* @param uuid The uuid of the player to be added to the database
*/
public void newUser(String playerName);
public void newUser(String playerName, UUID uuid);
/**
* Load a player from the database.
*
* @deprecated replaced by {@link #loadPlayerProfile(String playerName, UUID uuid, boolean createNew)}
*
* @param playerName The name of the player to load from the database
* @param createNew Whether to create a new record if the player is not
* found
* @return The player's data, or an unloaded PlayerProfile if not found
* and createNew is false
*/
@Deprecated
public PlayerProfile loadPlayerProfile(String playerName, boolean createNew);
/**
* Load a player from the database.
*
* @param uuid The uuid of the player to load from the database
* @return The player's data, or an unloaded PlayerProfile if not found
*/
public PlayerProfile loadPlayerProfile(UUID uuid);
/**
* Load a player from the database. Attempt to use uuid, fall back on playername
*
* @param playerName The name of the player to load from the database
* @param uuid The uuid of the player to load from the database
* @param createNew Whether to create a new record if the player is not
* found
* @return The player's data, or an unloaded PlayerProfile if not found
* and createNew is false
*/
public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean createNew);
/**
* Get all users currently stored in the database.
*
@@ -95,10 +120,19 @@ public interface DatabaseManager {
*/
public void convertUsers(DatabaseManager destination);
public boolean saveUserUUID(String userName, UUID uuid);
public boolean saveUserUUIDs(Map<String, UUID> fetchedUUIDs);
/**
* Retrieve the type of database in use. Custom databases should return CUSTOM.
*
* @return The type of database
*/
public DatabaseType getDatabaseType();
/**
* Called when the plugin disables
*/
public void onDisable();
}

View File

@@ -2,7 +2,6 @@ package com.gmail.nossr50.database;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
@@ -10,10 +9,12 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
@@ -26,6 +27,7 @@ import com.gmail.nossr50.datatypes.database.UpgradeType;
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.runnables.database.UUIDUpdateAsyncTask;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.StringUtils;
@@ -44,6 +46,10 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
usersFile = new File(mcMMO.getUsersFilePath());
checkStructure();
updateLeaderboards();
if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS)) {
new UUIDUpdateAsyncTask(mcMMO.p, getStoredUsers()).runTaskAsynchronously(mcMMO.p);
}
}
public void purgePowerlessUsers() {
@@ -80,7 +86,6 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
}
else {
purgedUsers++;
Misc.profileCleanup(character[0]);
}
}
@@ -92,8 +97,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
tryClose(in);
tryClose(out);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
@@ -135,7 +154,6 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
if (currentTime - lastPlayed > PURGE_TIME) {
removedPlayers++;
Misc.profileCleanup(name);
}
else {
if (rewrite) {
@@ -158,8 +176,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
tryClose(in);
tryClose(out);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
@@ -197,8 +229,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
tryClose(in);
tryClose(out);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
@@ -209,6 +255,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
public boolean saveUser(PlayerProfile profile) {
String playerName = profile.getPlayerName();
UUID uuid = profile.getUniqueId();
BufferedReader in = null;
FileWriter out = null;
@@ -223,8 +270,9 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
// While not at the end of the file
while ((line = in.readLine()) != null) {
// Read the line in and copy it to the output it's not the player we want to edit
if (!line.split(":")[0].equalsIgnoreCase(playerName)) {
// Read the line in and copy it to the output if it's not the player we want to edit
String[] character = line.split(":");
if (!character[41].equalsIgnoreCase(uuid.toString()) && !character[0].equalsIgnoreCase(playerName)) {
writer.append(line).append("\r\n");
}
else {
@@ -271,6 +319,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":");
writer.append(profile.getSkillLevel(SkillType.ALCHEMY)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":");
writer.append(uuid.toString()).append(":");
writer.append("\r\n");
}
}
@@ -285,8 +334,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
return false;
}
finally {
tryClose(in);
tryClose(out);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
}
@@ -313,7 +376,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
return skills;
}
public void newUser(String playerName) {
public void newUser(String playerName, UUID uuid) {
BufferedWriter out = null;
synchronized (fileWritingLock) {
try {
@@ -362,7 +425,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
out.append(Config.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD
out.append("0:"); // Alchemy
out.append("0:"); // AlchemyXp
out.append(uuid != null ? uuid.toString() : "NULL").append(":"); // UUID
// Add more in the same format as the line above
out.newLine();
@@ -371,12 +435,28 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
e.printStackTrace();
}
finally {
tryClose(out);
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
}
@Deprecated
public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
return loadPlayerProfile(playerName, null, false);
}
public PlayerProfile loadPlayerProfile(UUID uuid) {
return loadPlayerProfile("", uuid, false);
}
public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
BufferedReader in = null;
String usersFilePath = mcMMO.getUsersFilePath();
@@ -390,17 +470,36 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
// Find if the line contains the player we want.
String[] character = line.split(":");
if (!character[0].equalsIgnoreCase(playerName)) {
// Compare names because we don't have a valid uuid for that player even
// if input uuid is not null
if (character[41].equalsIgnoreCase("NULL")) {
if (!character[0].equalsIgnoreCase(playerName)) {
continue;
}
}
// If input uuid is not null then we should compare uuids
else if ((uuid != null && !character[41].equalsIgnoreCase(uuid.toString())) || (uuid == null && !character[0].equalsIgnoreCase(playerName))) {
continue;
}
// Update playerName in database after name change
if (!character[0].equalsIgnoreCase(playerName)) {
mcMMO.p.debug("Name change detected: " + character[0] + " => " + playerName);
character[0] = playerName;
}
return loadFromLine(character);
}
// Didn't find the player, create a new one
if (create) {
newUser(playerName);
return new PlayerProfile(playerName, true);
if (uuid == null) {
newUser(playerName, uuid);
return new PlayerProfile(playerName, true);
}
newUser(playerName, uuid);
return new PlayerProfile(playerName, uuid, true);
}
}
catch (Exception e) {
@@ -414,14 +513,18 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
in.close();
}
catch (IOException e) {
e.printStackTrace();
// Ignore
}
}
}
}
// Return unloaded profile
return new PlayerProfile(playerName);
if (uuid == null) {
return new PlayerProfile(playerName);
}
return new PlayerProfile(playerName, uuid);
}
public void convertUsers(DatabaseManager destination) {
@@ -453,11 +556,132 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
e.printStackTrace();
}
finally {
tryClose(in);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
}
public boolean saveUserUUID(String userName, UUID uuid) {
boolean worked = false;
BufferedReader in = null;
FileWriter out = null;
String usersFilePath = mcMMO.getUsersFilePath();
synchronized (fileWritingLock) {
try {
in = new BufferedReader(new FileReader(usersFilePath));
StringBuilder writer = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
String[] character = line.split(":");
if (!worked && character[0].equalsIgnoreCase(userName)) {
if (character.length < 42) {
mcMMO.p.getLogger().severe("Could not update UUID for " + userName + "!");
mcMMO.p.getLogger().severe("Database entry is invalid.");
break;
}
line = line.replace(character[41], uuid.toString());
worked = true;
}
writer.append(line).append("\r\n");
}
out = new FileWriter(usersFilePath); // Write out the new file
out.write(writer.toString());
}
catch (Exception e) {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
return worked;
}
public boolean saveUserUUIDs(Map<String, UUID> fetchedUUIDs) {
BufferedReader in = null;
FileWriter out = null;
String usersFilePath = mcMMO.getUsersFilePath();
synchronized (fileWritingLock) {
try {
in = new BufferedReader(new FileReader(usersFilePath));
StringBuilder writer = new StringBuilder();
String line;
while (((line = in.readLine()) != null) && !fetchedUUIDs.isEmpty()) {
String[] character = line.split(":");
if (fetchedUUIDs.containsKey(character[0])) {
if (character.length < 42) {
mcMMO.p.getLogger().severe("Could not update UUID for " + character[0] + "!");
mcMMO.p.getLogger().severe("Database entry is invalid.");
continue;
}
character[41] = fetchedUUIDs.remove(character[0]).toString();
line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
}
writer.append(line).append("\r\n");
}
out = new FileWriter(usersFilePath); // Write out the new file
out.write(writer.toString());
}
catch (Exception e) {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
return true;
}
public List<String> getStoredUsers() {
ArrayList<String> users = new ArrayList<String>();
BufferedReader in = null;
@@ -478,7 +702,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
e.printStackTrace();
}
finally {
tryClose(in);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
return users;
@@ -548,7 +779,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " during user " + playerName + " (Are you sure you formatted it correctly?) " + e.toString());
}
finally {
tryClose(in);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
@@ -598,6 +836,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
in = new BufferedReader(new FileReader(usersFilePath));
StringBuilder writer = new StringBuilder();
String line;
HashSet<String> usernames = new HashSet<String>();
HashSet<String> players = new HashSet<String>();
while ((line = in.readLine()) != null) {
@@ -612,8 +851,13 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
}
String[] character = line.split(":");
// Prevent the same username from being present multiple times
if (!usernames.add(character[0])) {
continue;
}
// Prevent the same player from being present multiple times
if (!players.add(character[0])) {
if (character.length == 42 && (!character[41].isEmpty() && !players.add(character[41]))) {
continue;
}
@@ -645,7 +889,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
}
// If they're valid, rewrite them to the file.
if (character.length == 41) {
if (character.length == 42) {
writer.append(line).append("\r\n");
continue;
}
@@ -699,16 +943,25 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
oldVersion = "1.4.08";
}
}
if (character.length <= 41) {
// Addition of UUIDs
// Version 1.5.01
// Add a value because otherwise it gets removed
newLine.append("NULL:");
if (oldVersion == null) {
oldVersion = "1.5.01";
}
}
// Remove any blanks that shouldn't be there, and validate the other fields
String[] newCharacter = newLine.toString().split(":");
boolean corrupted = false;
for (int i = 0; i < newCharacter.length; i++) {
if (newCharacter[i].isEmpty() && !(i == 2 || i == 3 || i == 23 || i == 33)) {
if (newCharacter[i].isEmpty() && !(i == 2 || i == 3 || i == 23 || i == 33 || i == 41)) {
corrupted = true;
if (newCharacter.length != 41) {
if (newCharacter.length != 42) {
newCharacter = (String[]) ArrayUtils.remove(newCharacter, i);
}
else {
@@ -729,7 +982,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
newCharacter[i] = Config.getInstance().getMobHealthbarDefault().toString();
}
if (!StringUtils.isInt(newCharacter[i]) && !(i == 0 || i == 2 || i == 3 || i == 23 || i == 33 || i == 38)) {
if (!StringUtils.isInt(newCharacter[i]) && !(i == 0 || i == 2 || i == 3 || i == 23 || i == 33 || i == 38 || i == 41)) {
corrupted = true;
newCharacter[i] = "0";
}
@@ -740,7 +993,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
}
if (oldVersion != null) {
mcMMO.p.debug("Updating database line for player " + character[0] + " from before version " + oldVersion);
mcMMO.p.debug("Updating database line from before version " + oldVersion + " for player " + character[0]);
}
if (corrupted || oldVersion != null) {
@@ -759,8 +1012,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
}
finally {
tryClose(in);
tryClose(out);
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// Ignore
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
@@ -785,18 +1052,6 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
}
}
private void tryClose(Closeable c) {
if (c == null) {
return;
}
try {
c.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
if (statsList == null) {
return null;
@@ -829,8 +1084,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
private PlayerProfile loadFromLine(String[] character) {
Map<SkillType, Integer> skills = getSkillMapFromLine(character); // Skill levels
Map<SkillType, Float> skillsXp = new HashMap<SkillType, Float>(); // Skill & XP
Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
Map<SkillType, Float> skillsXp = new EnumMap<SkillType, Float>(SkillType.class); // Skill & XP
Map<AbilityType, Integer> skillsDATS = new EnumMap<AbilityType, Integer>(AbilityType.class); // Ability & Cooldown
MobHealthbarType mobHealthbarType;
// TODO on updates, put new values in a try{} ?
@@ -869,11 +1124,19 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
}
return new PlayerProfile(character[0], skills, skillsXp, skillsDATS, mobHealthbarType);
UUID uuid;
try {
uuid = UUID.fromString(character[41]);
}
catch (Exception e) {
uuid = null;
}
return new PlayerProfile(character[0], uuid, skills, skillsXp, skillsDATS, mobHealthbarType);
}
private Map<SkillType, Integer> getSkillMapFromLine(String[] character) {
Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level
Map<SkillType, Integer> skills = new EnumMap<SkillType, Integer>(SkillType.class); // Skill & Level
skills.put(SkillType.TAMING, Integer.valueOf(character[24]));
skills.put(SkillType.MINING, Integer.valueOf(character[1]));
@@ -895,4 +1158,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
public DatabaseType getDatabaseType() {
return DatabaseType.FLATFILE;
}
@Override
public void onDisable() { }
}

View File

@@ -7,5 +7,7 @@ public enum UpgradeType {
ADD_MOB_HEALTHBARS,
DROP_SQL_PARTY_NAMES,
DROP_SPOUT,
ADD_ALCHEMY;
ADD_ALCHEMY,
ADD_UUIDS,
ADD_UUIDS_PARTY;
}

View File

@@ -0,0 +1,55 @@
package com.gmail.nossr50.datatypes.experience;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.skills.SkillType;
public class SkillXpGain implements Delayed {
private final long expiryTime;
private final float xp;
private final SkillType type;
public SkillXpGain(SkillType type, float xp) {
this.expiryTime = System.currentTimeMillis() + getDuration();
this.xp = xp;
this.type = type;
}
public SkillType getSkill() {
return type;
}
public float getXp() {
return xp;
}
private static long getDuration() {
return TimeUnit.MINUTES.toMillis(ExperienceConfig.getInstance().getDiminishedReturnsTimeInterval());
}
public int compareTo(SkillXpGain other) {
if (this.expiryTime < other.expiryTime) {
return -1;
}
else if (this.expiryTime > other.expiryTime) {
return 1;
}
return 0;
}
@Override
public int compareTo(Delayed other) {
if (other instanceof SkillXpGain) {
// Use more efficient method if possible (private fields)
return this.compareTo((SkillXpGain) other);
}
return (int) (getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS));
}
@Override
public long getDelay(TimeUnit arg0) {
return arg0.convert(expiryTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
}

View File

@@ -2,8 +2,10 @@ package com.gmail.nossr50.datatypes.party;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
@@ -20,9 +22,10 @@ import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Misc;
public class Party {
private final LinkedHashSet<String> members = new LinkedHashSet<String>();
private final LinkedHashMap<UUID, String> members = new LinkedHashMap<UUID, String>();
private final List<Player> onlineMembers = new ArrayList<Player>();
private String leader;
private PartyLeader leader;
private String name;
private String password;
private boolean locked;
@@ -43,14 +46,14 @@ public class Party {
this.name = name;
}
public Party(String leader, String name) {
public Party(PartyLeader leader, String name) {
this.leader = leader;
this.name = name;
this.locked = true;
this.level = 0;
}
public Party(String leader, String name, String password) {
public Party(PartyLeader leader, String name, String password) {
this.leader = leader;
this.name = name;
this.password = password;
@@ -58,7 +61,7 @@ public class Party {
this.level = 0;
}
public Party(String leader, String name, String password, boolean locked) {
public Party(PartyLeader leader, String name, String password, boolean locked) {
this.leader = leader;
this.name = name;
this.password = password;
@@ -66,21 +69,11 @@ public class Party {
this.level = 0;
}
public LinkedHashSet<String> getMembers() {
public LinkedHashMap<UUID, String> getMembers() {
return members;
}
public List<Player> getOnlineMembers() {
List<Player> onlineMembers = new ArrayList<Player>();
for (String memberName : members) {
Player member = mcMMO.p.getServer().getPlayerExact(memberName);
if (member != null) {
onlineMembers.add(member);
}
}
return onlineMembers;
}
@@ -97,11 +90,19 @@ public class Party {
return onlinePlayerNames;
}
public boolean addOnlineMember(Player player) {
return onlineMembers.add(player);
}
public boolean removeOnlineMember(Player player) {
return onlineMembers.remove(player);
}
public String getName() {
return name;
}
public String getLeader() {
public PartyLeader getLeader() {
return leader;
}
@@ -133,7 +134,7 @@ public class Party {
this.name = name;
}
public void setLeader(String leader) {
public void setLeader(PartyLeader leader) {
this.leader = leader;
}
@@ -220,7 +221,8 @@ public class Party {
}
if (!Config.getInstance().getPartyInformAllMembers()) {
Player leader = mcMMO.p.getServer().getPlayer(this.leader);
Player leader = mcMMO.p.getServer().getPlayer(this.leader.getUniqueId());
if (leader != null) {
leader.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, getLevel()));
@@ -303,13 +305,24 @@ public class Party {
}
}
public boolean hasMember(String memberName) {
return this.getMembers().values().contains(memberName);
}
public boolean hasMember(UUID uuid) {
return this.getMembers().keySet().contains(uuid);
}
public String createMembersList(String playerName, List<Player> nearMembers) {
StringBuilder memberList = new StringBuilder();
for (String memberName : this.getMembers()) {
Player member = mcMMO.p.getServer().getPlayerExact(memberName);
for (Entry<UUID, String> memberEntry : this.getMembers().entrySet()) {
UUID uuid = memberEntry.getKey();
String memberName = memberEntry.getValue();
if (this.getLeader().equalsIgnoreCase(memberName)) {
Player member = mcMMO.p.getServer().getPlayer(uuid);
if (this.getLeader().getUniqueId().equals(uuid)) {
memberList.append(ChatColor.GOLD);
if (member == null) {

View File

@@ -0,0 +1,21 @@
package com.gmail.nossr50.datatypes.party;
import java.util.UUID;
public class PartyLeader {
private UUID uuid;
private String playerName;
public PartyLeader(UUID uuid, String playerName) {
this.uuid = uuid;
this.playerName = playerName;
}
public UUID getUniqueId() {
return uuid;
}
public String getPlayerName() {
return playerName;
}
}

View File

@@ -3,15 +3,14 @@ package com.gmail.nossr50.datatypes.player;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
@@ -92,15 +91,24 @@ public class McMMOPlayer {
private boolean isUsingUnarmed;
private final FixedMetadataValue playerMetadata;
public McMMOPlayer(Player player) {
public McMMOPlayer(Player player, PlayerProfile profile) {
String playerName = player.getName();
UUID uuid = player.getUniqueId();
this.player = player;
playerMetadata = new FixedMetadataValue(mcMMO.p, playerName);
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true);
party = PartyManager.getPlayerParty(playerName);
this.profile = profile;
party = PartyManager.getPlayerParty(playerName, uuid);
ptpRecord = new PartyTeleportRecord();
if (inParty()) {
loginParty();
}
if (profile.getUniqueId() == null) {
profile.setUniqueId(uuid);
}
/*
* I'm using this method because it makes code shorter and safer (we don't have to add all SkillTypes manually),
* but I actually have no idea about the performance impact, if there is any.
@@ -124,69 +132,6 @@ public class McMMOPlayer {
for (ToolType toolType : ToolType.values()) {
toolMode.put(toolType, false);
}
if (!profile.isLoaded()) {
mcMMO.p.getLogger().warning("Unable to load the PlayerProfile for " + playerName + ". Will retry over the next several seconds.");
new RetryProfileLoadingTask().runTaskTimerAsynchronously(mcMMO.p, 11L, 31L);
}
}
private class RetryProfileLoadingTask extends BukkitRunnable {
private static final int MAX_TRIES = 5;
private final String playerName = McMMOPlayer.this.player.getName();
private int attempt = 0;
// WARNING: ASYNC TASK
// DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE
@Override
public void run() {
// Quit if they logged out
if (!player.isOnline()) {
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + playerName + " - player logged out");
this.cancel();
return;
}
// Send the message that we're doing the recovery
if (attempt == 0) {
player.sendMessage(LocaleLoader.getString("Recovery.Notice"));
}
// Increment attempt counter and try
attempt++;
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true);
// If successful, schedule the apply
if (profile.isLoaded()) {
new ApplySuccessfulProfile(profile).runTask(mcMMO.p);
player.sendMessage(LocaleLoader.getString("Recovery.Success"));
this.cancel();
return;
}
// If we've failed five times, give up
if (attempt >= MAX_TRIES) {
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + playerName);
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Recovery.AdminFailureNotice", playerName), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
player.sendMessage(LocaleLoader.getString("Recovery.Failure").split("\n"));
this.cancel();
return;
}
}
}
private class ApplySuccessfulProfile extends BukkitRunnable {
private final PlayerProfile profile;
private ApplySuccessfulProfile(PlayerProfile profile) {
this.profile = profile;
}
// Synchronized task
// No database access permitted
@Override
public void run() {
McMMOPlayer.this.profile = profile;
}
}
public AcrobaticsManager getAcrobaticsManager() {
@@ -636,6 +581,14 @@ public class McMMOPlayer {
allianceInvite = null;
}
public void loginParty() {
party.addOnlineMember(this.getPlayer());
}
public void logoutParty() {
party.removeOnlineMember(this.getPlayer());
}
public int getItemShareModifier() {
if (itemShareModifier < 10) {
setItemShareModifier(10);

View File

@@ -3,12 +3,15 @@ package com.gmail.nossr50.datatypes.player;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.DelayQueue;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.datatypes.experience.SkillXpGain;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.runnables.player.PlayerProfileSaveTask;
@@ -19,6 +22,7 @@ import com.google.common.collect.ImmutableMap;
public class PlayerProfile {
private final String playerName;
private UUID uuid;
private boolean loaded;
private volatile boolean changed;
@@ -30,7 +34,17 @@ public class PlayerProfile {
private final Map<SkillType, Float> skillsXp = new HashMap<SkillType, Float>(); // Skill & XP
private final Map<AbilityType, Integer> abilityDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
// Store previous XP gains for deminished returns
private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<SkillXpGain>();
private HashMap<SkillType, Float> rollingSkillsXp = new HashMap<SkillType, Float>();
@Deprecated
public PlayerProfile(String playerName) {
this(playerName, null);
}
public PlayerProfile(String playerName, UUID uuid) {
this.uuid = uuid;
this.playerName = playerName;
mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
@@ -45,13 +59,20 @@ public class PlayerProfile {
}
}
@Deprecated
public PlayerProfile(String playerName, boolean isLoaded) {
this(playerName);
this.loaded = isLoaded;
}
public PlayerProfile(String playerName, Map<SkillType, Integer> levelData, Map<SkillType, Float> xpData, Map<AbilityType, Integer> cooldownData, MobHealthbarType mobHealthbarType) {
public PlayerProfile(String playerName, UUID uuid, boolean isLoaded) {
this(playerName, uuid);
this.loaded = isLoaded;
}
public PlayerProfile(String playerName, UUID uuid, Map<SkillType, Integer> levelData, Map<SkillType, Float> xpData, Map<AbilityType, Integer> cooldownData, MobHealthbarType mobHealthbarType) {
this.playerName = playerName;
this.uuid = uuid;
this.mobHealthbarType = mobHealthbarType;
skills.putAll(levelData);
@@ -71,11 +92,11 @@ public class PlayerProfile {
}
// TODO should this part be synchronized?
PlayerProfile profileCopy = new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType);
PlayerProfile profileCopy = new PlayerProfile(playerName, uuid, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType);
changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
if (changed) {
mcMMO.p.getLogger().warning("PlayerProfile for " + playerName + " failed to save");
mcMMO.p.getLogger().warning("PlayerProfile saving failed for player: " + playerName + " " + uuid);
}
}
@@ -83,6 +104,16 @@ public class PlayerProfile {
return playerName;
}
public UUID getUniqueId() {
return uuid;
}
public void setUniqueId(UUID uuid) {
changed = true;
this.uuid = uuid;
}
public boolean isLoaded() {
return loaded;
}
@@ -189,6 +220,16 @@ public class PlayerProfile {
skillsXp.put(skill, skillsXp.get(skill) - xp);
}
public void removeXp(SkillType skill, float xp) {
if (skill.isChildSkill()) {
return;
}
changed = true;
skillsXp.put(skill, skillsXp.get(skill) - xp);
}
/**
* Modify a skill level.
*
@@ -239,7 +280,46 @@ public class PlayerProfile {
}
/**
* Get the total amount of Xp before the next level.
* Get the registered amount of experience gained
* This is used for diminished XP returns
*
* @return xp Experience amount registered
*/
public float getRegisteredXpGain(SkillType skillType) {
float xp = 0F;
if (rollingSkillsXp.get(skillType) != null) {
xp = rollingSkillsXp.get(skillType);
}
return xp;
}
/**
* Register an experience gain
* This is used for diminished XP returns
*
* @param skillType Skill being used
* @param xp Experience amount to add
*/
public void registerXpGain(SkillType skillType, float xp) {
gainedSkillsXp.add(new SkillXpGain(skillType, xp));
rollingSkillsXp.put(skillType, getRegisteredXpGain(skillType) + xp);
}
/**
* Remove experience gains older than a given time
* This is used for diminished XP returns
*/
public void purgeExpiredXpGains() {
SkillXpGain gain;
while ((gain = gainedSkillsXp.poll()) != null) {
rollingSkillsXp.put(gain.getSkill(), getRegisteredXpGain(gain.getSkill()) - gain.getXp());
}
}
/**
* Get the amount of Xp remaining before the next level.
*
* @param skillType Type of skill to check
* @return the total amount of Xp until next level

View File

@@ -85,30 +85,67 @@ public enum AbilityType {
this.abilityPlayerOff = abilityPlayerOff;
}
/**
* Get the cooldown time in seconds for this ability
*
* @return cooldown time in seconds
*/
public int getCooldown() {
return Config.getInstance().getCooldown(this);
}
/**
* Get the maximum length in seconds for this ability
*
* @return maximum length in seconds
*/
public int getMaxLength() {
return Config.getInstance().getMaxLength(this);
}
/**
* Get the locale string for when the ability activates
*
* @return localized activation message
*/
public String getAbilityOn() {
return LocaleLoader.getString(this.abilityOn);
}
/**
* Get the locale string for when the ability deactivates
*
* @return localized deactivation message
*/
public String getAbilityOff() {
return LocaleLoader.getString(this.abilityOff);
}
/**
* Get the locale string for nearby players when someone activates this ability
*
* @param player {@link Player} object that activates this ability
* @return localized activation message
*/
public String getAbilityPlayer(Player player) {
return LocaleLoader.getString(this.abilityPlayer, player.getName());
}
/**
* Get the locale string for nearby players when someone deactivates this ability
*
* @param player {@link Player} object that deactivates this ability
* @return localized deactivation message
*/
public String getAbilityPlayerOff(Player player) {
return LocaleLoader.getString(this.abilityPlayerOff, player.getName());
}
/**
* Get ability refresh message
*
* @return Localized ability refresh message
*/
public String getAbilityRefresh() {
return LocaleLoader.getString(this.abilityRefresh);
}

View File

@@ -0,0 +1,22 @@
package com.gmail.nossr50.datatypes.skills;
public enum ModConfigType {
BLOCKS,
TOOLS,
ARMOR,
UNKNOWN;
public static ModConfigType getModConfigType(String materialName) {
if (materialName.contains("HELM") || (materialName.contains("CHEST") && !materialName.contains("CHESTNUT")) || materialName.contains("LEGS") || materialName.contains("LEGGINGS") || materialName.contains("BOOT")) {
return ARMOR;
}
else if (materialName.contains("PICKAXE") || materialName.contains("AXE") || (materialName.contains("BOW") && !materialName.contains("BOWL")) || materialName.contains("HOE") || materialName.contains("SHOVEL") || materialName.contains("SWORD")) {
return TOOLS;
}
else if (materialName.contains("LOG") || materialName.contains("LEAVES") || materialName.contains("FLOWER") || materialName.contains("PLANT") || materialName.contains("CROP") || materialName.contains("ORE") || materialName.contains("DIRT") || materialName.contains("SAND") || materialName.contains("GRASS")) {
return BLOCKS;
}
return UNKNOWN;
}
}

View File

@@ -71,6 +71,7 @@ public enum SecondaryAbility {
SHARPENED_CLAWS,
SHOCK_PROOF,
THICK_FUR,
PUMMEL,
/* Unarmed */
BLOCK_CRACKER,

View File

@@ -48,7 +48,7 @@ public enum SkillType {
SALVAGE(SalvageManager.class, Color.ORANGE, ImmutableList.of(SecondaryAbility.ADVANCED_SALVAGE, SecondaryAbility.ARCANE_SALVAGE)),
SMELTING(SmeltingManager.class, Color.YELLOW, ImmutableList.of(SecondaryAbility.FLUX_MINING, SecondaryAbility.FUEL_EFFICIENCY, SecondaryAbility.SECOND_SMELT)),
SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), AbilityType.SERRATED_STRIKES, ToolType.SWORD, ImmutableList.of(SecondaryAbility.BLEED, SecondaryAbility.COUNTER)),
TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SecondaryAbility.BEAST_LORE, SecondaryAbility.CALL_OF_THE_WILD, SecondaryAbility.ENVIROMENTALLY_AWARE, SecondaryAbility.FAST_FOOD, SecondaryAbility.GORE, SecondaryAbility.HOLY_HOUND, SecondaryAbility.SHARPENED_CLAWS, SecondaryAbility.SHOCK_PROOF, SecondaryAbility.THICK_FUR)),
TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SecondaryAbility.BEAST_LORE, SecondaryAbility.CALL_OF_THE_WILD, SecondaryAbility.ENVIROMENTALLY_AWARE, SecondaryAbility.FAST_FOOD, SecondaryAbility.GORE, SecondaryAbility.HOLY_HOUND, SecondaryAbility.SHARPENED_CLAWS, SecondaryAbility.SHOCK_PROOF, SecondaryAbility.THICK_FUR, SecondaryAbility.PUMMEL)),
UNARMED(UnarmedManager.class, Color.BLACK, AbilityType.BERSERK, ToolType.FISTS, ImmutableList.of(SecondaryAbility.BLOCK_CRACKER, SecondaryAbility.DEFLECT, SecondaryAbility.DISARM, SecondaryAbility.IRON_ARM, SecondaryAbility.IRON_GRIP)),
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, AbilityType.TREE_FELLER, ToolType.AXE, ImmutableList.of(SecondaryAbility.LEAF_BLOWER, SecondaryAbility.WOODCUTTING_DOUBLE_DROPS));

View File

@@ -1,18 +1,47 @@
package com.gmail.nossr50.events.hardcore;
import java.util.HashMap;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class McMMOPlayerDeathPenaltyEvent extends PlayerEvent implements Cancellable {
private HashMap<String, Integer> levelChanged;
private HashMap<String, Float> experienceChanged;
private boolean cancelled;
public McMMOPlayerDeathPenaltyEvent(Player player, HashMap<String, Integer> levelChanged, HashMap<String, Float> experienceChanged) {
super(player);
this.levelChanged = levelChanged;
this.experienceChanged = experienceChanged;
this.cancelled = false;
}
@Deprecated
public McMMOPlayerDeathPenaltyEvent(Player player) {
super(player);
this.cancelled = false;
}
public HashMap<String, Integer> getLevelChanged() {
return levelChanged;
}
public void setLevelChanged(HashMap<String, Integer> levelChanged) {
this.levelChanged = levelChanged;
}
public HashMap<String, Float> getExperienceChanged() {
return experienceChanged;
}
public void setExperienceChanged(HashMap<String, Float> experienceChanged) {
this.experienceChanged = experienceChanged;
}
/** Following are required for Cancellable **/
@Override
public boolean isCancelled() {

View File

@@ -0,0 +1,38 @@
package com.gmail.nossr50.events.hardcore;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class McMMOPlayerPreDeathPenaltyEvent extends PlayerEvent implements Cancellable {
private boolean cancelled;
public McMMOPlayerPreDeathPenaltyEvent(Player player) {
super(player);
this.cancelled = false;
}
/** Following are required for Cancellable **/
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/** Rest of file is required boilerplate for custom events **/
private static final HandlerList handlers = new HandlerList();
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,12 @@
package com.gmail.nossr50.events.hardcore;
import java.util.HashMap;
import org.bukkit.entity.Player;
public class McMMOPlayerStatLossEvent extends McMMOPlayerDeathPenaltyEvent {
public McMMOPlayerStatLossEvent(Player player, HashMap<String, Integer> levelChanged, HashMap<String, Float> experienceChanged) {
super(player, levelChanged, experienceChanged);
}
}

View File

@@ -0,0 +1,18 @@
package com.gmail.nossr50.events.hardcore;
import java.util.HashMap;
import org.bukkit.entity.Player;
public class McMMOPlayerVampirismEvent extends McMMOPlayerDeathPenaltyEvent {
private boolean isVictim;
public McMMOPlayerVampirismEvent(Player player, boolean isVictim, HashMap<String, Integer> levelChanged, HashMap<String, Float> experienceChanged) {
super(player, levelChanged, experienceChanged);
this.isVictim = isVictim;
}
public boolean isVictim() {
return isVictim;
}
}

View File

@@ -615,7 +615,7 @@ public class EntityListener implements Listener {
Player player = (Player) target;
Tameable tameable = (Tameable) entity;
if (!CombatUtils.isFriendlyPet(player, tameable)) {
if (!UserManager.hasPlayerDataKey(player) || !CombatUtils.isFriendlyPet(player, tameable)) {
return;
}

View File

@@ -41,7 +41,7 @@ import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.ShareHandler;
import com.gmail.nossr50.runnables.commands.McScoreboardKeepTask;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
@@ -140,9 +140,8 @@ public class PlayerListener implements Listener {
Player killer = killedPlayer.getKiller();
if (statLossEnabled || (killer != null && vampirismEnabled)) {
if (EventUtils.callDeathPenaltyEvent(killedPlayer).isCancelled()) {
if (EventUtils.callPreDeathPenaltyEvent(killedPlayer).isCancelled()) {
return;
}
@@ -368,6 +367,10 @@ public class PlayerListener implements Listener {
mcMMOPlayer.getProfile().scheduleAsyncSave();
UserManager.remove(player);
ScoreboardManager.teardownPlayer(player);
if (mcMMOPlayer.inParty()) {
mcMMOPlayer.logoutParty();
}
}
/**
@@ -387,9 +390,7 @@ public class PlayerListener implements Listener {
return;
}
McMMOPlayer mcMMOPlayer = UserManager.addUser(player);
mcMMOPlayer.actualizeRespawnATS();
ScoreboardManager.setupPlayer(player);
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
Motd.displayAll(player);
@@ -403,11 +404,6 @@ public class PlayerListener implements Listener {
player.sendMessage(LocaleLoader.getString("UpdateChecker.Outdated"));
player.sendMessage(LocaleLoader.getString("UpdateChecker.NewAvailable"));
}
if (Config.getInstance().getShowStatsAfterLogin()) {
ScoreboardManager.enablePlayerStatsScoreboard(player);
new McScoreboardKeepTask(player).runTaskLater(mcMMO.p, 1 * Misc.TICK_CONVERSION_FACTOR);
}
}
/**
@@ -471,6 +467,7 @@ public class PlayerListener implements Listener {
// Make sure the player knows what he's doing when trying to salvage an enchanted item
if (!(heldItem.getEnchantments().size() > 0) || salvageManager.checkConfirmation(true)) {
SkillUtils.handleAbilitySpeedDecrease(player);
salvageManager.handleSalvage(block.getLocation(), heldItem);
player.updateInventory();
}

View File

@@ -6,10 +6,13 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerXpGainEvent;
import com.gmail.nossr50.events.skills.abilities.McMMOPlayerAbilityActivateEvent;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
public class SelfListener implements Listener {
@@ -38,4 +41,46 @@ public class SelfListener implements Listener {
public void onAbility(McMMOPlayerAbilityActivateEvent event) {
ScoreboardManager.cooldownUpdate(event.getPlayer(), event.getSkill());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerXpGain(McMMOPlayerXpGainEvent event) {
SkillType skillType = event.getSkill();
int threshold = ExperienceConfig.getInstance().getDiminishedReturnsThreshold(skillType);
if (threshold <= 0 || !ExperienceConfig.getInstance().getDiminishedReturnsEnabled()) {
// Diminished returns is turned off
return;
}
final float rawXp = event.getRawXpGained();
if (rawXp < 0) {
// Don't calculate for XP subtraction
return;
}
Player player = event.getPlayer();
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (skillType.isChildSkill()) {
return;
}
float modifiedThreshold = (float) (threshold / skillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
float difference = (mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) - modifiedThreshold) / modifiedThreshold;
if (difference > 0) {
// System.out.println("Total XP Earned: " + mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) + " / Threshold value: " + threshold);
// System.out.println(difference * 100 + "% over the threshold!");
// System.out.println("Previous: " + event.getRawXpGained());
// System.out.println("Adjusted XP " + (event.getRawXpGained() - (event.getRawXpGained() * difference)));
float newValue = rawXp - (rawXp * difference);
if (newValue > 0) {
event.setRawXpGained(newValue);
}
else {
event.setCancelled(true);
}
}
}
}

View File

@@ -14,6 +14,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.mods.ArmorConfigManager;
import com.gmail.nossr50.config.mods.BlockConfigManager;
import com.gmail.nossr50.config.mods.EntityConfigManager;
@@ -38,6 +39,8 @@ import com.gmail.nossr50.runnables.UpdaterResultAsyncTask;
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
import com.gmail.nossr50.runnables.database.UserPurgeTask;
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
import com.gmail.nossr50.runnables.player.ClearRegisteredXPGainTask;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.skills.alchemy.Alchemy;
@@ -115,6 +118,7 @@ public class mcMMO extends JavaPlugin {
public final static String playerDataKey = "mcMMO: Player Data";
public final static String greenThumbDataKey = "mcMMO: Green Thumb";
public final static String pistonDataKey = "mcMMO: Piston State";
public final static String databaseCommandKey = "mcMMO: Processing Database Command";
public static FixedMetadataValue metadataValue;
@@ -167,8 +171,7 @@ public class mcMMO extends JavaPlugin {
holidayManager = new HolidayManager();
for (Player player : getServer().getOnlinePlayers()) {
UserManager.addUser(player); // In case of reload add all users back into UserManager
ScoreboardManager.setupPlayer(player);
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
}
debug("Version " + getDescription().getVersion() + " is enabled!");
@@ -242,6 +245,7 @@ public class mcMMO extends JavaPlugin {
}
}
databaseManager.onDisable();
debug("Was disabled."); // How informative!
}
@@ -468,10 +472,10 @@ public class mcMMO extends JavaPlugin {
long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
if (purgeIntervalTicks == 0) {
new UserPurgeTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
new UserPurgeTask().runTaskLaterAsynchronously(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
}
else if (purgeIntervalTicks > 0) {
new UserPurgeTask().runTaskTimer(this, purgeIntervalTicks, purgeIntervalTicks);
new UserPurgeTask().runTaskTimerAsynchronously(this, purgeIntervalTicks, purgeIntervalTicks);
}
// Automatically remove old members from parties
@@ -490,6 +494,11 @@ public class mcMMO extends JavaPlugin {
if (getHolidayManager().nearingAprilFirst()) {
new CheckDateTask().runTaskTimer(this, 10L * Misc.TICK_CONVERSION_FACTOR, 1L * 60L * 60L * Misc.TICK_CONVERSION_FACTOR);
}
// Clear the registered XP data so players can earn XP again
if (ExperienceConfig.getInstance().getDiminishedReturnsEnabled()) {
new ClearRegisteredXPGainTask().runTaskTimer(this, 60, 60);
}
}
private void checkModConfigs() {

View File

@@ -2,8 +2,10 @@ package com.gmail.nossr50.party;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
@@ -13,10 +15,13 @@ import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.chat.ChatMode;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.datatypes.party.ItemShareType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyLeader;
import com.gmail.nossr50.datatypes.party.ShareMode;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.events.party.McMMOPartyAllianceChangeEvent;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
@@ -132,10 +137,10 @@ public final class PartyManager {
* @param player The player to check
* @return all the players in the player's party
*/
public static LinkedHashSet<String> getAllMembers(Player player) {
public static LinkedHashMap<UUID, String> getAllMembers(Player player) {
Party party = getParty(player);
return party == null ? new LinkedHashSet<String>() : party.getMembers();
return party == null ? new LinkedHashMap<UUID, String>() : party.getMembers();
}
/**
@@ -184,9 +189,33 @@ public final class PartyManager {
* @param playerName The members name
* @return the existing party, null otherwise
*/
@Deprecated
public static Party getPlayerParty(String playerName) {
for (Party party : parties) {
if (party.getMembers().contains(playerName)) {
if (party.getMembers().keySet().contains(playerName)) {
return party;
}
}
return null;
}
/**
* Retrieve a party by a members uuid
*
* @param uuid The members uuid
* @return the existing party, null otherwise
*/
public static Party getPlayerParty(String playerName, UUID uuid) {
for (Party party : parties) {
LinkedHashMap<UUID, String> members = party.getMembers();
if (members.keySet().contains(uuid) || members.values().contains(playerName)) {
// Name changes
if (members.get(uuid) == null || !members.get(uuid).equals(playerName)) {
members.put(uuid, playerName);
}
return party;
}
}
@@ -222,18 +251,22 @@ public final class PartyManager {
* @param party The party
*/
public static void removeFromParty(OfflinePlayer player, Party party) {
LinkedHashSet<String> members = party.getMembers();
LinkedHashMap<UUID, String> members = party.getMembers();
String playerName = player.getName();
members.remove(playerName);
members.remove(player.getUniqueId());
if (player.isOnline()) {
party.getOnlineMembers().remove(player.getPlayer());
}
if (members.isEmpty()) {
parties.remove(party);
}
else {
// If the leaving player was the party leader, appoint a new leader from the party members
if (party.getLeader().equalsIgnoreCase(playerName)) {
setPartyLeader(members.iterator().next(), party);
if (party.getLeader().getUniqueId().equals(player.getUniqueId())) {
setPartyLeader(members.keySet().iterator().next(), party);
}
informPartyMembersQuit(party, playerName);
@@ -277,9 +310,8 @@ public final class PartyManager {
*/
public static void createParty(McMMOPlayer mcMMOPlayer, String partyName, String password) {
Player player = mcMMOPlayer.getPlayer();
String playerName = player.getName();
Party party = new Party(playerName, partyName.replace(".", ""), password);
Party party = new Party(new PartyLeader(player.getUniqueId(), player.getName()), partyName.replace(".", ""), password);
if (password != null) {
player.sendMessage(LocaleLoader.getString("Party.Password.Set", password));
@@ -408,11 +440,13 @@ public final class PartyManager {
* @param party The party
*/
public static void addToParty(McMMOPlayer mcMMOPlayer, Party party) {
String playerName = mcMMOPlayer.getPlayer().getName();
Player player = mcMMOPlayer.getPlayer();
String playerName = player.getName();
informPartyMembersJoin(party, playerName);
mcMMOPlayer.setParty(party);
party.getMembers().add(playerName);
party.getMembers().put(player.getUniqueId(), player.getName());
party.getOnlineMembers().add(player);
}
/**
@@ -421,36 +455,37 @@ public final class PartyManager {
* @param partyName The party name
* @return the leader of the party
*/
public static String getPartyLeader(String partyName) {
public static String getPartyLeaderName(String partyName) {
Party party = getParty(partyName);
return party == null ? null : party.getLeader();
return party == null ? null : party.getLeader().getPlayerName();
}
/**
* Set the leader of a party.
*
* @param playerName The name of the player to set as leader
* @param uuid The uuid of the player to set as leader
* @param party The party
*/
public static void setPartyLeader(String playerName, Party party) {
String leaderName = party.getLeader();
public static void setPartyLeader(UUID uuid, Party party) {
OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(uuid);
UUID leaderUniqueId = party.getLeader().getUniqueId();
for (Player member : party.getOnlineMembers()) {
String memberName = member.getName();
UUID memberUniqueId = member.getUniqueId();
if (memberName.equalsIgnoreCase(playerName)) {
if (memberUniqueId.equals(player.getUniqueId())) {
member.sendMessage(LocaleLoader.getString("Party.Owner.Player"));
}
else if (memberName.equalsIgnoreCase(leaderName)) {
else if (memberUniqueId.equals(leaderUniqueId)) {
member.sendMessage(LocaleLoader.getString("Party.Owner.NotLeader"));
}
else {
member.sendMessage(LocaleLoader.getString("Party.Owner.New", playerName));
member.sendMessage(LocaleLoader.getString("Party.Owner.New", player.getName()));
}
}
party.setLeader(playerName);
party.setLeader(new PartyLeader(player.getUniqueId(), player.getName()));
}
/**
@@ -461,7 +496,7 @@ public final class PartyManager {
public static boolean canInvite(McMMOPlayer mcMMOPlayer) {
Party party = mcMMOPlayer.getParty();
return !party.isLocked() || party.getLeader().equalsIgnoreCase(mcMMOPlayer.getPlayer().getName());
return !party.isLocked() || party.getLeader().getUniqueId().equals(mcMMOPlayer.getPlayer().getUniqueId());
}
/**
@@ -472,6 +507,11 @@ public final class PartyManager {
return;
}
if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS_PARTY)) {
loadAndUpgradeParties();
return;
}
YamlConfiguration partiesFile = YamlConfiguration.loadConfiguration(partyFile);
ArrayList<Party> hasAlly = new ArrayList<Party>();
@@ -479,7 +519,8 @@ public final class PartyManager {
for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
Party party = new Party(partyName);
party.setLeader(partiesFile.getString(partyName + ".Leader"));
String[] leaderSplit = partiesFile.getString(partyName + ".Leader").split("[|]");
party.setLeader(new PartyLeader(UUID.fromString(leaderSplit[0]), leaderSplit[1]));
party.setPassword(partiesFile.getString(partyName + ".Password"));
party.setLocked(partiesFile.getBoolean(partyName + ".Locked"));
party.setLevel(partiesFile.getInt(partyName + ".Level"));
@@ -496,18 +537,19 @@ public final class PartyManager {
party.setSharingDrops(itemShareType, partiesFile.getBoolean(partyName + ".ItemShareType." + itemShareType.toString(), true));
}
List<String> memberNames = partiesFile.getStringList(partyName + ".Members");
LinkedHashSet<String> members = party.getMembers();
LinkedHashMap<UUID, String> members = party.getMembers();
for (String memberName : memberNames) {
members.add(memberName);
for (String memberEntry : partiesFile.getStringList(partyName + ".Members")) {
String[] memberSplit = memberEntry.split("[|]");
members.put(UUID.fromString(memberSplit[0]), memberSplit[1]);
}
parties.add(party);
}
mcMMO.p.debug("Loaded (" + parties.size() + ") Parties...");
for (Party party : hasAlly) {
party.setAlly(getParty(partiesFile.getString(party.getName() + ".Ally")));
party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally")));
}
}
@@ -527,8 +569,9 @@ public final class PartyManager {
mcMMO.p.debug("Saving Parties... (" + parties.size() + ")");
for (Party party : parties) {
String partyName = party.getName();
PartyLeader leader = party.getLeader();
partiesFile.set(partyName + ".Leader", party.getLeader());
partiesFile.set(partyName + ".Leader", leader.getUniqueId().toString() + "|" + leader.getPlayerName());
partiesFile.set(partyName + ".Password", party.getPassword());
partiesFile.set(partyName + ".Locked", party.isLocked());
partiesFile.set(partyName + ".Level", party.getLevel());
@@ -541,15 +584,18 @@ public final class PartyManager {
partiesFile.set(partyName + ".ItemShareType." + itemShareType.toString(), party.sharingDrops(itemShareType));
}
List<String> memberNames = new ArrayList<String>();
List<String> members = new ArrayList<String>();
for (String member : party.getMembers()) {
if (!memberNames.contains(member)) {
memberNames.add(member);
for (Entry<UUID, String> memberEntry : party.getMembers().entrySet()) {
String memberUniqueId = memberEntry.getKey() == null ? "" : memberEntry.getKey().toString();
String memberName = memberEntry.getValue();
if (!members.contains(memberName)) {
members.add(memberUniqueId + "|" + memberName);
}
}
partiesFile.set(partyName + ".Members", memberNames);
partiesFile.set(partyName + ".Members", members);
}
try {
@@ -560,6 +606,73 @@ public final class PartyManager {
}
}
private static void loadAndUpgradeParties() {
YamlConfiguration partiesFile = YamlConfiguration.loadConfiguration(partyFile);
if (!partyFile.renameTo(new File(mcMMO.getFlatFileDirectory() + "parties.yml.converted"))) {
mcMMO.p.getLogger().severe("Could not rename parties.yml to parties.yml.converted!");
return;
}
ArrayList<Party> hasAlly = new ArrayList<Party>();
for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
Party party = new Party(partyName);
String leaderName = partiesFile.getString(partyName + ".Leader");
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(leaderName, false);
if (!profile.isLoaded()) {
mcMMO.p.getLogger().warning("Could not find UUID in database for party leader " + leaderName + " in party " + partyName);
continue;
}
UUID leaderUniqueId = profile.getUniqueId();
party.setLeader(new PartyLeader(leaderUniqueId, leaderName));
party.setPassword(partiesFile.getString(partyName + ".Password"));
party.setLocked(partiesFile.getBoolean(partyName + ".Locked"));
party.setLevel(partiesFile.getInt(partyName + ".Level"));
party.setXp(partiesFile.getInt(partyName + ".Xp"));
if (partiesFile.getString(partyName + ".Ally") != null) {
hasAlly.add(party);
}
party.setXpShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ExpShareMode", "NONE")));
party.setItemShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ItemShareMode", "NONE")));
for (ItemShareType itemShareType : ItemShareType.values()) {
party.setSharingDrops(itemShareType, partiesFile.getBoolean(partyName + ".ItemShareType." + itemShareType.toString(), true));
}
LinkedHashMap<UUID, String> members = party.getMembers();
for (String memberName : partiesFile.getStringList(partyName + ".Members")) {
PlayerProfile memberProfile = mcMMO.getDatabaseManager().loadPlayerProfile(memberName, false);
if (!memberProfile.isLoaded()) {
mcMMO.p.getLogger().warning("Could not find UUID in database for party member " + memberName + " in party " + partyName);
continue;
}
UUID memberUniqueId = memberProfile.getUniqueId();
members.put(memberUniqueId, memberName);
}
parties.add(party);
}
mcMMO.p.debug("Loaded (" + parties.size() + ") Parties...");
for (Party party : hasAlly) {
party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally")));
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS_PARTY);
}
/**
* Handle party change event.
*

View File

@@ -37,6 +37,7 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
if (useChat) {
displayChat();
}
((Player) sender).removeMetadata(mcMMO.databaseCommandKey, mcMMO.p);
}
private void displayChat() {

View File

@@ -7,6 +7,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.database.PlayerStat;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -41,6 +42,9 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
displayChat();
}
if (sender instanceof Player) {
((Player) sender).removeMetadata(mcMMO.databaseCommandKey, mcMMO.p);
}
sender.sendMessage(LocaleLoader.getString("Commands.mctop.Tip"));
}

View File

@@ -1,39 +0,0 @@
package com.gmail.nossr50.runnables.database;
import java.lang.ref.WeakReference;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.database.SQLDatabaseManager;
/**
* This task is in charge of sending a MySQL ping over the MySQL connection
* every hour to prevent the connection from timing out and losing players'
* data when they join.
* <p/>
* A WeakReference is used to keep the database instance, because
* {@link com.gmail.nossr50.commands.database.ConvertDatabaseCommand database
* conversion} may create a SQLDatabaseManager that will be thrown out. If a
* normal reference was used, the conversion would cause a combined data and
* resource leak through this task.
*/
public class SQLDatabaseKeepaliveTask extends BukkitRunnable {
WeakReference<SQLDatabaseManager> databaseInstance;
public SQLDatabaseKeepaliveTask(SQLDatabaseManager dbman) {
databaseInstance = new WeakReference<SQLDatabaseManager>(dbman);
}
public void run() {
SQLDatabaseManager dbman = databaseInstance.get();
if (dbman != null) {
dbman.checkConnected();
}
else {
// This happens when the database was started for a conversion,
// or discarded by its creator for any other reason. If this code
// was not present, we would leak the connection resources.
this.cancel();
}
}
}

View File

@@ -1,22 +0,0 @@
package com.gmail.nossr50.runnables.database;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.util.player.UserManager;
public class SQLReconnectTask extends BukkitRunnable {
@Override
public void run() {
if (((SQLDatabaseManager) mcMMO.getDatabaseManager()).checkConnected()) {
UserManager.saveAll(); // Save all profiles
UserManager.clearAll(); // Clear the profiles
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
UserManager.addUser(player); // Add in new profiles, forcing them to 'load' again from MySQL
}
}
}
}

View File

@@ -0,0 +1,91 @@
package com.gmail.nossr50.runnables.database;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.database.DatabaseManager;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.uuid.UUIDFetcher;
public class UUIDUpdateAsyncTask extends BukkitRunnable {
private mcMMO plugin;
private static final int MAX_LOOKUP = Math.max(HiddenConfig.getInstance().getUUIDConvertAmount(), 100);
private static final int RATE_LIMIT = HiddenConfig.getInstance().getMojangRateLimit();
private static final long LIMIT_PERIOD = HiddenConfig.getInstance().getMojangLimitPeriod();
private static final int BATCH_SIZE = 5000;
private List<String> userNames;
private int size;
private int checkedUsers;
private long startMillis;
public UUIDUpdateAsyncTask(mcMMO plugin, List<String> userNames) {
this.plugin = plugin;
this.userNames = userNames;
this.checkedUsers = 0;
this.startMillis = System.currentTimeMillis();
}
@Override
public void run() {
size = userNames.size();
plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
List<String> userNamesSection;
Map<String, UUID> fetchedUUIDs = new HashMap<String, UUID>();
while (size != 0) {
if (checkedUsers + 100 > RATE_LIMIT) {
try {
Thread.sleep(LIMIT_PERIOD);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
startMillis = System.currentTimeMillis();
checkedUsers = 0;
}
if (size > MAX_LOOKUP) {
userNamesSection = userNames.subList(size - MAX_LOOKUP, size);
size -= MAX_LOOKUP;
}
else {
userNamesSection = userNames.subList(0, size);
size = 0;
}
try {
fetchedUUIDs.putAll(new UUIDFetcher(userNamesSection).call());
}
catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Unable to fetch UUIDs!", e);
return;
}
checkedUsers += userNamesSection.size();
userNamesSection.clear();
size = userNames.size();
Misc.printProgress(checkedUsers, DatabaseManager.progressInterval, startMillis);
if (fetchedUUIDs.size() > BATCH_SIZE) {
mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs);
fetchedUUIDs = new HashMap<String, UUID>();
}
}
if (fetchedUUIDs.size() == 0 || mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs)) {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
plugin.getLogger().info("UUID upgrade completed!");
}
}
}

View File

@@ -1,17 +1,22 @@
package com.gmail.nossr50.runnables.database;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
public class UserPurgeTask extends BukkitRunnable {
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
lock.lock();
mcMMO.getDatabaseManager().purgePowerlessUsers();
if (Config.getInstance().getOldUsersCutoff() != -1) {
mcMMO.getDatabaseManager().purgeOldUsers();
}
lock.unlock();
}
}

View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
import org.bukkit.scheduler.BukkitRunnable;
@@ -19,21 +20,21 @@ public class PartyAutoKickTask extends BukkitRunnable {
@Override
public void run() {
HashMap<OfflinePlayer, Party> toRemove = new HashMap<OfflinePlayer, Party>();
List<String> processedPlayers = new ArrayList<String>();
List<UUID> processedPlayers = new ArrayList<UUID>();
long currentTime = System.currentTimeMillis();
for (Party party : PartyManager.getParties()) {
for (String memberName : party.getMembers()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberName);
boolean isProcessed = processedPlayers.contains(memberName);
for (UUID memberUniqueId : party.getMembers().keySet()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberUniqueId);
boolean isProcessed = processedPlayers.contains(memberUniqueId);
if ((!member.isOnline() && (currentTime - member.getLastPlayed() > KICK_TIME)) || isProcessed) {
toRemove.put(member, party);
}
if (!isProcessed) {
processedPlayers.add(memberName);
processedPlayers.add(memberUniqueId);
}
}
}

View File

@@ -31,7 +31,7 @@ public class PartyChatTask extends BukkitRunnable {
@Override
public void run() {
if (Config.getInstance().getPartyChatColorLeaderName() && senderName.equalsIgnoreCase(party.getLeader())) {
if (Config.getInstance().getPartyChatColorLeaderName() && senderName.equalsIgnoreCase(party.getLeader().getPlayerName())) {
message = message.replaceFirst(Pattern.quote(displayName), ChatColor.GOLD + Matcher.quoteReplacement(displayName) + ChatColor.RESET);
}

View File

@@ -0,0 +1,15 @@
package com.gmail.nossr50.runnables.player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.util.player.UserManager;
public class ClearRegisteredXPGainTask extends BukkitRunnable {
@Override
public void run() {
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
mcMMOPlayer.getProfile().purgeExpiredXpGains();
}
}
}

View File

@@ -0,0 +1,92 @@
package com.gmail.nossr50.runnables.player;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.commands.McScoreboardKeepTask;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
public class PlayerProfileLoadingTask extends BukkitRunnable {
private static final int MAX_TRIES = 5;
private final Player player;
private int attempt = 0;
public PlayerProfileLoadingTask(Player player) {
this.player = player;
}
private PlayerProfileLoadingTask(Player player, int attempt) {
this.player = player;
this.attempt = attempt;
}
// WARNING: ASYNC TASK
// DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE
@Override
public void run() {
// Quit if they logged out
if (!player.isOnline()) {
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out");
return;
}
// Increment attempt counter and try
attempt++;
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getName(), player.getUniqueId(), true);
// If successful, schedule the apply
if (profile.isLoaded()) {
new ApplySuccessfulProfile(profile).runTask(mcMMO.p);
return;
}
// If we've failed five times, give up
if (attempt >= MAX_TRIES) {
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + player.getName());
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.AdminFailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
player.sendMessage(LocaleLoader.getString("Profile.Loading.Failure").split("\n"));
return;
}
new PlayerProfileLoadingTask(player, attempt).runTaskLaterAsynchronously(mcMMO.p, 100 * attempt);
}
private class ApplySuccessfulProfile extends BukkitRunnable {
private final PlayerProfile profile;
private ApplySuccessfulProfile(PlayerProfile profile) {
this.profile = profile;
}
// Synchronized task
// No database access permitted
@Override
public void run() {
if (!player.isOnline()) {
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out");
return;
}
McMMOPlayer mcMMOPlayer = new McMMOPlayer(player, profile);
UserManager.track(mcMMOPlayer);
mcMMOPlayer.actualizeRespawnATS();
ScoreboardManager.setupPlayer(player);
if (Config.getInstance().getShowProfileLoadedMessage()) {
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
}
if (Config.getInstance().getShowStatsAfterLogin()) {
ScoreboardManager.enablePlayerStatsScoreboard(player);
new McScoreboardKeepTask(player).runTaskLater(mcMMO.p, 1 * Misc.TICK_CONVERSION_FACTOR);
}
}
}
}

View File

@@ -6,7 +6,7 @@ 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.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.AbilityType;
import com.gmail.nossr50.util.EventUtils;
@@ -39,7 +39,7 @@ public class AbilityDisableTask extends BukkitRunnable {
// Fallthrough
case BERSERK:
if (HiddenConfig.getInstance().resendChunksAfterBlockAbility()) {
if (Config.getInstance().getRefreshChunksEnabled()) {
resendChunkRadiusAt(player, 1);
}
// Fallthrough

View File

@@ -19,10 +19,26 @@ public final class Acrobatics {
private Acrobatics() {};
/**
* Calculates how much damage should be dealt when Dodging
*
* @param damage the base damage
* @param damageModifier the damage modifier
*
* @return modified damage
*/
protected static double calculateModifiedDodgeDamage(double damage, double damageModifier) {
return Math.max(damage / damageModifier, 1.0);
}
/**
* Calculates how much damage should be dealt when Rolling
*
* @param damage the base damage
* @param damageThreshold the damage threshold
*
* @return modified damage
*/
protected static double calculateModifiedRollDamage(double damage, double damageThreshold) {
return Math.max(damage - damageThreshold, 0.0);
}

View File

@@ -28,10 +28,22 @@ public class AcrobaticsManager extends SkillManager {
super(mcMMOPlayer, SkillType.ACROBATICS);
}
/**
* Check if the player is allowed to use Roll,
* checks permissions and exploit prevention.
*
* @return true if the player is allowed to use Roll
*/
public boolean canRoll() {
return !exploitPrevention() && Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.ROLL);
}
/**
* Check if the player is allowed to use Dodge
*
* @param damager {@link Entity} that caused damage
* @return true if the player can Dodge damage from damager
*/
public boolean canDodge(Entity damager) {
if (Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.DODGE)) {
if (damager instanceof LightningStrike && Acrobatics.dodgeLightningDisabled) {
@@ -142,19 +154,33 @@ public class AcrobaticsManager extends SkillManager {
}
Location fallLocation = player.getLocation();
int maxTries = Config.getInstance().getAcrobaticsAFKMaxTries();
boolean sameLocation = (lastFallLocation != null && Misc.isNear(lastFallLocation, fallLocation, 2));
fallTries = sameLocation ? fallTries + 1 : Math.max(fallTries - 1, 0);
fallTries = sameLocation ? Math.min(fallTries + 1, maxTries) : Math.max(fallTries - 1, 0);
lastFallLocation = fallLocation;
return fallTries > Config.getInstance().getAcrobaticsAFKMaxTries();
return fallTries + 1 > maxTries;
}
/**
* Check if a fall is fatal
*
* @param damage amount of damage taken from the fall
* @return true if the fall is fatal, false otherwise
*/
private boolean isFatal(double damage) {
return getPlayer().getHealth() - damage <= 0;
}
/**
* Calculate the amount of XP gained from falling
*
* @param damage amount of damage taken in the fall
* @param isRoll boolean if the player was rolling
* @return amount of XP gained
*/
private float calculateRollXP(double damage, boolean isRoll) {
ItemStack boots = getPlayer().getInventory().getBoots();
float xp = (float) (damage * (isRoll ? Acrobatics.rollXpModifier : Acrobatics.fallXpModifier));

View File

@@ -134,7 +134,10 @@ public final class AlchemyPotionBrewer {
if (output != null && player != null) {
PotionStage potionStage = PotionStage.getPotionStage(input, output);
UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
if (UserManager.hasPlayerDataKey(player)) {
UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
}
}
}

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