Implemented a locale system using resource bundles.

This approach avoids having to have a huge class with default text in
it. The ResourceBundle loaded YamlResourceBundle does the conversion
from YAML.
This commit is contained in:
tastybento 2017-06-11 16:30:34 -07:00
parent c95f149901
commit 12792f388e
10 changed files with 1014 additions and 136 deletions

577
locales/bsb_en_US.yml Executable file
View File

@ -0,0 +1,577 @@
###########################################################################################
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
# the one at http://yaml-online-parser.appspot.com #
###########################################################################################
### Credits ###
# Tastybento: maintainer
# Poslovitch: maintainer
#
# This translation is adapted to version : [4.0]
not-setup:
header: |-
More set up is required before the plugin can start...
Edit config.yml. Then restart server.
distance: "Make sure you set island distance. If upgrading, set it to what it was before."
generator: |-
The world generator for the island world is not registered.
Potential reasons are:
1. If you are configuring the island world as the only server world
Make sure you have added the world to bukkit.yml
2. You reloaded instead of restarting the server. Reboot and try again.
generator-multiverse: " 3. Your Multiverse plugin is out of date. Upgrade to the latest version."
world-name: |-
The world name in config.yml is different to the world name in islands.yml.
If this is intentional, we assume you are doing a full reset.
If so, delete islands.yml and the previous world.
If not, correct the world name in config.yml and restart. This is probably the case if you are upgrading.
config-outdated: |-
The config.yml file looks outdated.
Make sure you updated your configuration after upgrading.
If this error is still happening, you probably edited the old config rather than editing the new one.
If so, please remove the current config.yml, work on config.new.yml and rename it to config.yml.
general:
success: "Success!"
errors:
no-permission: "You don't have permission to execute this command."
use-in-game: "This command is only available in game."
# TODO: These are legacy strings and should be converted to a better format but will do for now
acidBottle: "Acid Bottle"
acidBucket: "Acid Bucket"
acidLore: |
Do
not drink!
Beware!
adminDeleteIsland:
error: "Use &ldeleteisland confirm &r&cto delete the island you are on."
noid: "Cannot identify island."
use: "Use &ldelete [name] &r&cto delete the player instead."
adminHelp:
add: "adds player to leader's team"
addrange: "adds to or substracts from the island's protection range"
clearreset: "resets the island reset limit for player"
clearresetall: "resets the island reset limit for all players"
cobblestats: "displays magic cobble generation stats"
completeChallenge: "marks a challenge as complete"
delete: "delete an island (removes blocks)."
help: "Admin Commands:"
info: "info for the given player"
infoisland: "provide info on the nearest island"
kick: "removes player from any team"
level: "provide detailed island level report on player"
listChallengeResets: "lists challenge reset schedules, if any"
lock: "locks/unlocks player's island"
purge: "delete inactive islands older than [TimeInDays]."
purgeallowdisallow: "allow/disallow island to be purged if it meets purge criteria"
purgeholes: "free up island holes for reuse"
purgeunowned: "remove unowned islands"
name: "Set name of player's island"
register: "set a player's island to your location"
reload: "reload configuration from file."
resetAllChallenges: "resets all of the player's challenges"
resetChallenge: "marks a challenge as incomplete"
resetChallengeForAll: "globally resets a challenge for every player with an optional repetition"
resetname: "Reset name of player's island"
resetsign: "Resets the sign you are looking at to the island owner"
setbiome: "sets leader's island biome"
setdeaths: "sets player's death count"
setlanguage: "sets the default language and resets every player to that language"
setrange: "changes the island's protection range"
setspawn: "sets the island world spawn to a location close to you"
settingsreset: "Resets all islands to default protection settings"
teamChatSpy: "Spy on team chats (on/off)"
topTen: "manually update the top 10 list"
topbreeders: "lists most populated islands currently loaded"
tp: "Teleport to a player's island"
tpnether: "Teleport to a player's nether island"
unregister: "deletes a player without deleting the island blocks"
adminInfo:
bannedPlayers: "Banned players"
errorNullTeamLeader: "Team leader should be null!"
errorTeamMembersExist: "Player has team members, but shouldn't!"
hoppers: "Island has [number] hoppers"
islandLocation: "Island Location"
isLocked: "Island is locked"
isProtected: "Island is purge protected"
isSpawn: "Island is spawn"
isUnlocked: "Island is unlocked"
isUnprotected: "Island is not purge protected"
lastLogin: "Last login"
maxSize: "Island max size (distance)"
player: "Player"
teamLeader: "Team Leader"
teamMembers: "Team Members"
title: "This is spawn island"
unowned: "This island is not owned by anyone right now."
adminLock:
adminLockedIsland: "Admin locked your island"
adminUnlockedIsland: "Admin unlocked your island"
errorInGame: "Must use command in-game while on an island!"
adminRegister:
hadIsland: "[name] had an island at [location]"
leadsTeam: "[name] leads a team. Kick players from it first."
noIsland: "There is no known island in this area!"
notSpawn: "You cannot take ownership of spawn!"
taking: "Taking ownership away from [name]"
adminResetChallengeForAll:
error: "Format for repeat time must is [integer number][m/h/d] (minutes, hours, days), e.g. 5h"
repeating: "Repeating [duration]"
reset: "Reset [date]"
adminResetSign:
errorExists: "That warp sign is already active and owned by [name]"
found: "Warp sign found!"
noSign: "You must be looking at a sign post to run this command."
rescued: "Warp sign rescued and assigned to [name]"
adminReserve:
islandExists: "There is an island here already! Register the player instead!"
adminSetHome:
homeSet: "Home set to [location]"
noneFound: "No safe location found!"
notOnPlayersIsland: "You are not on the player's island"
notSafe: "That location is not safe"
adminSetRange:
invalid: "Invalid range!"
set: "Set new range to [number]"
tip: "Range must be between 10 to [max]"
updated: "Island range updated to [number]"
warning: "Warning - range is greater than island range [max]"
warning2: "Overlapped islands will act like spawn!"
adminSetSpawn:
center: "Island center [location]"
coords: "Protection coords [min] to [max]"
limits: "Island limits [min] to [max]"
locked: "Spawn is locked!"
move: "Move further away or unregister the owner."
ownedBy: "This island space is owned by [name]"
range: "Protection range = [number]"
set: "Set island spawn to your location."
setting: "Setting island spawn to your location [location]"
adminTeam:
addLeaderNoIsland: "Team leader does not have their own island so cannot have a team!"
addLeaderToOwn: "Cannot add a leader to their own team."
addedLeader: "Added the leader to this team!"
addingPlayer: "Adding player to team."
alreadyOnTeam: "Player was already on this team!"
kickLeader: "That player is a team leader. Remove team members first. Use '/[label] info [name]' to find team members."
nowUnowned: "[name] had an island at [location] that will become unowned now. You may want to delete it manually."
settingHome: "Setting player's home to the leader's home location"
adminTopBreeders:
checking: "Checking [number] islands..."
finding: "Finding top breeders..."
nothing: "No creatures found."
adminTopTen:
finished: "Finished generation of the Top Ten list"
generating: "Generating the Top Ten list"
adminTp:
manualWarp: "No safe spot found. Manually warp to somewhere near [location]."
adminUnregister:
keepBlocks: "Removing player from world, but keeping island at [location]"
onTeam: "Player is in a team - disband it first."
ban:
alreadybanned: "[name] is already banned!"
banned: "You are banned from [name]'s island!"
fail: "[name] cannot be banned!"
helpBan: "ban a player from your island."
helpBanList: "list banned players."
helpUnban: "un-ban a player from your island."
lifted: "Ban lifted from [name]'s island!"
liftedsuccess: "Ban lifted for [name]!"
none: "None"
notbanned: "[name] is not banned!"
notteammember: "You cannot ban a team member!"
notyourself: "You cannot do that to yourself!"
success: "[name] is banned from the island!"
biome:
help: "open the biomes GUI."
paneltitle: "Select A Biome"
set: "Island biome set to [biome]!"
unknown: "Unknown biome!"
youbought: "Purchased for [cost]!"
boats:
warning: "It's unsafe to exit the boat right now..."
challenges:
colors: "Challenges will have different colors depending on if they are:"
complete: "Complete"
completeNotRepeatable: "Completed(not repeatable)"
completeRepeatable: "Completed(repeatable)"
completedtimes: "Completed [donetimes] out of [maxtimes]"
errorIslandLevel: "Your island must be level [level] to complete this challenge!"
errorItemsNotThere: "All required items must be close to you on your island!"
errorNotCloseEnough: "You must be standing within [number] blocks of all required items."
errorNotEnoughItems: "You do not have enough required item(s)"
errorNotOnIsland: "You must be on your island to do that!"
errorRewardProblem: "There was a problem giving your reward. Ask Admin to check log!"
erroryouaremissing: "You are missing"
expReward: "Exp reward"
firstTimeRewards: "First time reward(s)"
guititle: "ASkyBlock Challenges"
help1: "Use /c <name> to view information about a challenge."
help2: "Use /c complete <name> to attempt to complete that challenge."
incomplete: "Incomplete"
invalidChallengeName: "Invalid challenge name! Use /c help for more information"
itemTakeWarning: "All required items are taken when you complete this challenge!"
level: "Level"
maxreached: "Max reached [donetimes] out of [maxtimes]"
moneyReward: "Money reward"
name: "Challenge Name"
nameHasCompleted: "[name] has completed the [challenge] challenge!"
navigation: "Click to see [level] challenges!"
notRepeatable: "This Challenge is not repeatable!"
repeatRewards: "Repeat reward(s)"
rewards: "Reward(s)"
toComplete: "Complete [challengesToDo] more [thisLevel] challenges to unlock this level!"
toCompleteUse: "To complete this challenge, use"
unknownChallenge: "Unknown challenge name (check spelling)!"
youHaveCompleted: "You have completed the [challenge] challenge!"
youHaveNotUnlocked: "You have not unlocked this challenge yet!"
youRepeated: "You repeated the [challenge] challenge!"
changingObsidiantoLava: "Changing obsidian back into lava. Be careful!"
checkteam:
checkingTeam: "Checking Team of [name]"
completechallenge:
challangeCompleted: "Challenge: [challengename] has been completed for [name]"
errorChallengeDoesNotExist: "Challenge doesn't exist or is already completed"
confirm:
errorTimeLimitExpired: "Time limit expired! Issue command again."
coop:
cannotcoop: "Only island leader can coop a player."
help: "give a player full access to your island"
invited: "[name] made [player] a coop player!"
listcoops: "list coop players"
madeyoucoopy: "[name] made you a coop player!"
notincoop: "[name] is not in your coop!"
onyourteam: "Player is already on your team!"
removed: "[name] removed your coop status!"
removesuccess: "[name] is no longer a coop player."
success: "[name] is now a coop player until they log out or you uncoop or expel them."
uncoop: "remove full island access from player"
useexpel: "Use expel or uncoop to remove."
deaths:
deaths: "Deaths"
died: "died!"
leveldeaths: "&c[[number] deaths]"
delete:
removing: "Removing [name]'s island."
drankAcid: "drank acid."
drankAcidAndDied: "just drank acid and died."
error:
blockedbyapi: "A plugin using the API blocked this action."
commandNotReady: "You can't use that command right now."
maxIslands: "The world is full of islands! Try again later!"
noIsland: "You do not have an island!"
noIslandOther: "That player does not have an island!"
noPermission: "You don't have permission to use that command!"
notABlock: "That is not a block"
noTeam: "Player is not in a team."
notOnIsland: "You are not in an island space!"
offlinePlayer: "That player is offline or doesn't exist."
tooLong: "Too long. Maximum size is [length]."
tooShort: "Too short. Minimum size is [length]."
unknownCommand: "Unknown command."
unknownPlayer: "That player is unknown."
useInGame: "This command must be used in-game."
wrongWorld: "You cannot do that in this world."
minishopDisabled: "Minishop is disabled."
expel:
expelled: "You were expelled from that island!"
fail: "[name] cannot be expelled!"
notonisland: "Player is not trespassing on your island!"
notyourself: "You cannot expel yourself!"
success: "You expelled [name]!"
general:
success: "Success!"
invite:
errorCantJoinIsland: "You couldn't join the island, maybe it's full."
errorCoolDown: "You can invite that player again in [time] minutes"
errorThatPlayerIsAlreadyInATeam: "That player is already in a team."
errorYouCannotInviteYourself: "You can not invite yourself!"
errorYouMustHaveIslandToInvite: "You must have an island in order to invite people to it!"
errorYourIslandIsFull: "Your island is full, you can't invite anyone else."
hasJoinedYourIsland: "[name] has joined your island!"
help: "Use [/[label] invite <playername>] to invite a player to your island."
inviteSentTo: "Invite sent to [name]"
nameHasInvitedYou: "[name] has invited you to join their island!"
onlyIslandOwnerCanInvite: "Only the leader can invite!"
removingInvite: "Removing your previous invite."
toAcceptOrReject: "to accept or reject the invite."
warningYouWillLoseIsland: "WARNING: You will lose your current island if you accept!"
youCanInvite: "You can invite [number] more players."
youCannotInvite: "You can't invite any more players."
youHaveJoinedAnIsland: "You have joined an island! Use /[label] team to see the other members."
island:
blockValue: "[name] placed here may be worth [value]"
blockWorthless: "[name] is worthless"
cannotTeleport: "You cannot teleport when falling!"
donate: "Welcome to A SkyBlock by tastybento"
donatecolor: "aqua"
errorCouldNotCreateIsland: "Could not create your Island. Please contact a server moderator."
errorInvalidPlayer: "That player is invalid or does not have an island!"
errorLevelNotReady: "Can't use that command right now! Try again in a few seconds."
errorYouDoNotHavePermission: "You do not have permission to use that command!"
helpAcceptReject: "accept or reject an invitation."
helpChallenges: "/challenges: &fshow challenges"
helpColor: "&e"
helpControlPanel: "open the island GUI."
helpExpel: "force a player from your island."
helpInvite: "invite a player to join your island."
helpIsland: "start an island, or teleport to your island."
helpIslandSpawn: "go to spawn."
helpKick: "remove a team player from your island."
helpLeave: "leave another player's island."
helpLevel: "calculate your island level"
helpLevelPlayer: "see another player's island level."
helpLock: "Locks island so visitors cannot enter it"
helpMakeLeader: "transfer the island to <player>."
helpName: "Set a name for your island"
helpResetName: "reset your island name."
helpRestart: "restart your island and remove the old one."
helpSelectLanguage: "Select Language"
helpSetHome: "set your teleport point for /[label]."
helpSettings: "see island protection and game settings"
helpTeam: "view your team information."
helpTeleport: "teleport to your island."
helpTop: "see the top ranked islands."
helpValue: "see island level value of block in hand"
helpWarp: "Warp to <player>'s welcome sign."
helpWarps: "Lists all available welcome-sign warps."
islandDeletedLifeboats: "Island deleted! Head to the lifeboats!"
islandLevelis: "Island level is"
new: "Creating a new island for you..."
requiredPointsToNextLevel: "You need [points] more points to reach level [next]!"
resetConfirm: "Type /[label] confirm within [seconds] seconds to delete your island and restart!"
resetMustRemovePlayers: "You must remove all players from your island before you can restart it (/[label] kick <player>). See a list of players currently part of your island using /[label] team."
resetNoMore: "No more resets are allowed for your island!"
resetOnlyOwner: "Only the owner may restart this island. Leave this island in order to start your own (/[label] leave)."
resetPleaseWait: "Please wait, generating new island"
resetsLeft: "Resets left"
resetTo: "Cleared reset limit"
resetWait: "You have to wait [time] seconds before you can do that again."
resetYouHave: "You have [number] resets left."
subtitle: "by tastybento"
subtitlecolor: "blue"
teleport: "Teleporting you to your island. (/[label] help for more info)"
title: "A SkyBlock"
titlecolor: "gold"
unlimited: "Unlimited"
url: ""
islandProtected: "Island protected."
islandguardsettings:
TNTdamage: "TNT Damage"
allowed: "Allowed"
aciddamage: "Acid damage"
animalspawning: "Allow/Disallow Animal Spawning"
anvil: "Visitor anvil use"
armorstand: "Visitor armor stand use"
beacon: "Vistor beacon use"
bed: "Visitor bed use"
breakblocks: "Vistor block breaking"
breeding: "Vistor animal breeding"
brewingstand: "Visitor potion brewing"
bucket: "Visitor bucket use"
collectlava: "Visitor lava collection"
collectwater: "Visitor water collection"
chest: "Visitor chest use"
chestdamage: "Chest damage by TNT"
chorusfruit: "Visitor chorus fruit use"
creeperdamage: "Creeper damage"
creepergriefing: "Creeper griefing"
creeperpain: "Creeper explosions hurt"
croptrample: "Visitor crop trample"
disallowed: "Disallowed"
door: "Visitor door use"
eggs: "Visitor egg throwing"
enchantingtable: "Visitor enchanting"
enderpearl: "Visitor enderpearl use"
fire: "Fire"
fireextinguish: "Visitor fire extinguish"
firespread: "Fire spread"
furnace: "Visitor furnace use"
gate: "Visitor gate use"
horseinventoryaccess: "Visitor horse inventory access"
horseriding: "Visitor horse riding"
hurtanimals: "Visitor animal hurting"
hurtmonsters: "Visitor monster hurting"
joinleaveislandmessages: "Enter/exit island messages"
jukebox: "Visitor jukebox use"
leash: "Visitor leash use"
lever: "Visitor lever or button use"
milking: "Visitor cow milking"
monsterspawning: "Allow/Disallow Monster Spawning"
netherpvp: "Nether PvP"
placeblocks: "Visitor block placing"
portaluse: "Visitor portal use"
pressureplate: "Visitors activate pressure plates"
pvp: "PvP"
redstone: "Visitor redstone use"
settingsgeneraltitle: "World Settings"
settingsgeneraldesc: "General Island World Settings"
settingsislandtitle: "Island Settings"
settingsislanddesc: "Settings for this island"
settingsspawntitle: "Spawn Settings"
settingsspawndesc: "These rules apply at spawn"
shears: "Visitor sheep shearing"
spawnegg: "Spawn egg use"
teleportwhenfalling: "Teleport when falling"
title: "Island Guard Settings"
villagertrading: "Visitor villager trading"
visitordrop: "Visitor item drop"
visitorkeepitems: "Visitors keep items on death"
visitorpickup: "Visitor item pick-up"
withergriefing: "Wither griefing"
workbench: "Visitor workbench use"
kick:
errorNoTeam: "You do not have a team!"
errorNotPartOfTeam: "That player is not part of your island team!"
errorOnlyLeaderCan: "Only the leader can kick people off the island!"
errorPlayerNotInTeam: "That player is not in your team!"
nameRemoved: "[name] has been removed from the island."
nameRemovedYou: "[name] has removed you from their island!"
lavaTip: "Tip: If obsidian was not intended, it can be scooped back up again with a bucket."
leave:
canceled: "Leave canceled"
errorLeadersCannotLeave: "Leaders cannot leave an island. Make someone else the leader first."
errorYouAreTheLeader: "You cannot leave because you are the leader. Make someone the leader first."
errorYouCannotLeaveIsland: "You can't leave your island if you are the only person. Try restart if you want a new one!"
errorYouMustBeInWorld: "You must be in the island world to leave your team!"
nameHasLeftYourIsland: "[name] has left your island!"
warning: "Are you sure you want to leave the team? Type '[label] leave' again to confirm."
youHaveLeftTheIsland: "You have left the island and returned to the player spawn."
level:
calculating: "Calculating island level. This will take a few seconds..."
errornotYourIsland: "Only the leader can do that."
islandLevel: "Island level"
lock:
enteringspawn: "Entering Spawn"
islandlocked: "Island is locked to visitors"
leavingspawn: "Leaving Spawn"
locking: "Locking island"
nowentering: "Now entering [name]'s island"
nowleaving: "Now leaving [name]'s island"
unlocking: "Unlocking island"
makeleader:
errorGeneralError: "Could not change leaders."
errorNotYourIsland: "This isn't your island, so you can't give it away!"
errorPlayerMustBeOnline: "That player must be online to transfer the island."
errorRemoveAllPlayersFirst: "Remove all players from your team other than the player you are transferring to."
errorThatPlayerIsNotInTeam: "That player is not part of your island team!"
errorYouMustBeInTeam: "You must be in a team to transfer your island."
nameIsNowTheOwner: "[name] is now the owner of your island!"
youAreNowTheOwner: "You are now the owner of your island."
minishop:
buy: "Buy(Left click)"
buyproblem: "There was a problem purchasing [description]"
islandhelpMiniShop: "Opens the MiniShop"
outofstock: "Out Of Stock"
sell: "Sell(Right click)"
sellproblem: "You do not have enough [description] to sell."
title: "&EMiniShop"
youbought: "You bought [number] [description] for [price]"
youcannotafford: "You cannot afford [description]!"
yousold: "You sold [number] [description] for [price]"
moblimits:
entity: "Island [entity] limit of [number] reached!"
error: "Island animal breeding limit of [number] reached!"
hopper: "Island hopper limit of [number] reached!"
villager: "Island villager breeding limit of [number] reached!"
nether:
spawnisprotected: "The Nether spawn area is protected."
news:
headline: "[A Skyblock News] While you were offline..."
purge:
acidFound: "There are [number] unowned islands. Do '/acid purge unowned confirm' to delete them within 20 seconds."
allowPurge: "Purge protection removed"
alreadyRunning: "Purge is already running, please wait for it to finish!"
calculating: "Calculating which islands have been inactive for more than [time] days."
countingUnowned: "Counting unowned islands and checking player files. This could take some time..."
finished: "Finished purging of inactive islands."
maxPurge: "Max purge is [number] islands. Run purge again afterwards to purge more."
noneFound: "No inactive islands to remove."
nowWaiting: "Now waiting..."
preventPurge: "Island is protected from purging"
purgeCancelled: "Purge cancelled."
removingAt: "Removing island at location [location]"
removingName: "Purge: Removing [name]'s island"
skyblockFound: "There are [number] unowned islands. Do '/asadmin purge unowned confirm' to delete them within 20 seconds."
stillChecking: "Still checking player files..."
thisWillRemove: "[number] inactive islands found. Islands with level < [level] will be removed."
typeConfirm: "Type /[label] confirm to proceed within 10 seconds"
usage: "Usage: /[label] purge [TimeInDays]"
warning: "DANGER! Do not run this with players on the server! MAKE BACKUP OF WORLD!"
register:
errorBedrockNotFound: "Could not register the island!"
settingIsland: "Set [name]'s island to the nearest island."
reject:
nameHasRejectedInvite: "[name] has rejected your island invite!"
youHaveNotBeenInvited: "You had not been invited to join a team."
youHaveRejectedInvitation: "You have rejected the invitation to join an island."
reload:
configReloaded: "Configuration reloaded from file."
resetallchallenges:
success: "[name] has had all challenges reset."
resetchallenge:
challengeReset: "Challenge: [challengename] has been reset for [name]"
errorChallengeDoesNotExist: "Challenge doesn't exist or isn't yet completed"
schematics:
title: "Select island..."
sethome:
errorNoIsland: "You are not part of an island. Returning you the spawn area!"
errorNotOnIsland: "You must be within your island boundaries to set home!"
errorNumHomes: "Homes can be 1 to [max]"
homeSet: "Your island home has been set to your current location."
settingsReset:
done: "Done."
inprogress: "Protection settings being reset, please wait..."
sign:
line1: "&1[A Skyblock]"
line2: "[player]"
line3: "Do not fall!"
line4: "Beware!"
sign-acidisland:
line1: "&1[AcidIsland]"
line2: "[player]"
line3: "Water is acid!"
line4: "Beware!"
targetInPVPArea: "Target is in a no-PVP area!"
team:
listingMembers: "Listing your island members"
teamchat:
helpChat: "turn on/off team chat"
noTeam: "You are not in a team!"
noTeamAround: "None of your team are online!"
prefix: "[Team Chat]<{ISLAND_PLAYER}> "
spyoff: "Team chat spy off"
spyon: "Team chat spy on"
statusOff: "Team chat is off"
statusOn: "Team chat is on"
topTen:
errorExcluded: "FYI: You are excluded from the top ten as you do not have [perm]"
errorNotReady: "Top ten list not generated yet!"
guiHeading: "&E&L<!> Island: &6&N[name]&7 (#[rank])"
guiTitle: "Top 10 Islands"
header: "These are the Top 10 islands:"
warps:
deactivate: "Deactivating old sign!"
errorDoesNotExist: "That warp doesn't exist!"
errorDuplicate: "Sorry! There is a sign already in that location!"
errorNoPerm: "You do not have permission to place Welcome Signs yet!"
errorNoPlace: "You must be on your island to place a Welcome Sign!"
errorNoRemove: "You can only remove your own Welcome Sign!"
errorNoWarpsYet: "There are no warps available yet!"
errorNotReadyYet: "That warp is not ready yet. Try again later."
errorNotSafe: "That warp is not safe right now. Try again later."
errorNotEnoughLevel: "You do not have enough island levels to create a Welcome Sign!"
next: "Next"
playerWarped: "[name] &2warped to your island!"
previous: "Previous"
removed: "Welcome sign removed!"
signRemoved: "Your welcome sign was removed!"
success: "Welcome sign placed successfully!"
title: "Island warps"
warpTip: "Create a warp by placing a sign with [WELCOME] at the top."
warpToPlayersSign: "Warping to <player>'s welcome sign."
warpsAvailable: "The following warps are available"
welcomeLine: "[WELCOME]"

View File

@ -1,38 +0,0 @@
###########################################################################################
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
# the one at http://yaml-online-parser.appspot.com #
###########################################################################################
### Credits ###
# Tastybento: maintainer
# Poslovitch: maintainer
#
# This translation is adapted to version : [4.0]
not-setup:
header: |-
More set up is required before the plugin can start...
Edit config.yml. Then restart server.
distance: "Make sure you set island distance. If upgrading, set it to what it was before."
generator: |-
The world generator for the island world is not registered.
Potential reasons are:
1. If you are configuring the island world as the only server world
Make sure you have added the world to bukkit.yml
2. You reloaded instead of restarting the server. Reboot and try again.
generator-multiverse: " 3. Your Multiverse plugin is out of date. Upgrade to the latest version."
world-name: |-
The world name in config.yml is different to the world name in islands.yml.
If this is intentional, we assume you are doing a full reset.
If so, delete islands.yml and the previous world.
If not, correct the world name in config.yml and restart. This is probably the case if you are upgrading.
config-outdated: |-
The config.yml file looks outdated.
Make sure you updated your configuration after upgrading.
If this error is still happening, you probably edited the old config rather than editing the new one.
If so, please remove the current config.yml, work on config.new.yml and rename it to config.yml.
general:
success: "Success!"
errors:
no-permission: "You don't have permission to execute this command."

View File

@ -1,6 +1,10 @@
package us.tastybento.bskyblock;
import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Locale;
import java.util.UUID;
import org.bukkit.Material;
@ -19,6 +23,7 @@ import us.tastybento.bskyblock.database.managers.OfflineHistoryMessages;
import us.tastybento.bskyblock.database.managers.PlayersManager;
import us.tastybento.bskyblock.generators.IslandWorld;
import us.tastybento.bskyblock.schematics.SchematicsMgr;
import us.tastybento.bskyblock.util.FileLister;
import us.tastybento.bskyblock.util.VaultHelper;
/**
@ -27,6 +32,9 @@ import us.tastybento.bskyblock.util.VaultHelper;
* @author Poslovitch
*/
public class BSkyBlock extends JavaPlugin{
final static String LOCALE_FOLDER = "locales";
private static BSkyBlock plugin;
private HashMap<String, BSBLocale> locales = new HashMap<String, BSBLocale>();
@ -35,10 +43,10 @@ public class BSkyBlock extends JavaPlugin{
private PlayersManager playersManager;
private IslandsManager islandsManager;
private OfflineHistoryMessages offlineHistoryMessages;
// Schematics
private SchematicsMgr schematicsManager;
// Metrics
private Metrics metrics;
@ -56,7 +64,7 @@ public class BSkyBlock extends JavaPlugin{
Settings.dbName = "ASkyBlock";
Settings.dbUsername = "username";
Settings.dbPassword = "password";
*/
*/
playersManager = new PlayersManager(this);
islandsManager = new IslandsManager(this);
// Only load metrics if set to true in config
@ -74,7 +82,7 @@ public class BSkyBlock extends JavaPlugin{
getLogger().warning("Could not set up economy! - Running without an economy.");
Settings.useEconomy = false;
}
VaultHelper.setupPermissions();
// These items have to be loaded when the server has done 1 tick.
@ -97,7 +105,7 @@ public class BSkyBlock extends JavaPlugin{
// TODO: ideally this should be in a test class!
/*
UUID owner = UUID.fromString("ddf561c5-72b6-4ec6-a7ea-8b50a893beb2");
Island island = islandsManager.createIsland(new Location(getServer().getWorld("world"),0,0,0,0,0), owner);
// Add members
Set<UUID> randomSet = new HashSet<UUID>();
@ -118,15 +126,15 @@ public class BSkyBlock extends JavaPlugin{
island.setName("new name");
island.setPurgeProtected(true);
islandsManager.save(false);
getLogger().info("DEBUG: ************ Finished saving, now loading *************");
*/
playersManager.load();
islandsManager.load();
// Load schematics
// TODO: load these from config.yml
Settings.chestItems = new ItemStack[] {
@ -136,10 +144,14 @@ public class BSkyBlock extends JavaPlugin{
new ItemStack(Material.BONE,2),
new ItemStack(Material.COBBLESTONE,5),
new ItemStack(Material.SAPLING,2)
};
};
schematicsManager = new SchematicsMgr(plugin);
getCommand("island").setExecutor(new IslandCommand(plugin));
Settings.defaultLanguage = "en-US";
loadLocales();
/*
*DEBUG CODE
Island loadedIsland = islandsManager.getIsland(owner);
@ -150,7 +162,7 @@ public class BSkyBlock extends JavaPlugin{
for (Entry<SettingsFlag, Boolean> flag: loadedIsland.getFlags().entrySet()) {
getLogger().info("Flag " + flag.getKey().name() + " = " + flag.getValue());
}
*/
*/
// Save islands & players data asynchronously every X minutes
Settings.databaseBackupPeriod = 10 * 60 * 20;
plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable() {
@ -268,6 +280,59 @@ public class BSkyBlock extends JavaPlugin{
return locales.get(locale);
}
/**
* Loads all the locales available. If the locale folder does not exist, one will be created and
* filled with locale files from the jar.
*/
public void loadLocales() {
// Describe the filter - we only want files that are correctly named
FilenameFilter ymlFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//plugin.getLogger().info("DEBUG: filename = " + name);
if (name.toLowerCase().startsWith("bsb_") && name.toLowerCase().endsWith(".yml")) {
// See if this is a valid locale
//Locale localeObject = new Locale(name.substring(0, 2), name.substring(3, 5));
Locale localeObject = Locale.forLanguageTag(name.substring(4, name.length() - 4));
if (localeObject == null) {
plugin.getLogger().severe("Filename '" + name + "' is an unknown locale, skipping...");
return false;
}
return true;
} else {
if (name.toLowerCase().endsWith(".yml")) {
plugin.getLogger().severe("Filename '" + name + "' is not in the correct format for a locale file - skipping...");
}
return false;
}
}
};
// Run through the files and store the locales
File localeDir = new File(this.getDataFolder(), LOCALE_FOLDER);
// If the folder does not exist, then make it and fill with the locale files from the jar
if (!localeDir.exists()) {
localeDir.mkdir();
FileLister lister = new FileLister(this);
try {
for (String name : lister.listJar(LOCALE_FOLDER)) {
this.saveResource(name,true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Store all the locales available
for (String language : localeDir.list(ymlFilter)) {
try {
BSBLocale locale = new BSBLocale(this, language);
locales.put(locale.getLocaleId(), locale);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
/**
* Returns the player database
* @return the player database

View File

@ -1,41 +1,65 @@
package us.tastybento.bskyblock.config;
import java.io.File;
import java.util.HashMap;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Locale;
import java.util.ResourceBundle;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.ChatColor;
import us.tastybento.bskyblock.BSkyBlock;
/**
* Contains all the texts sent to players.
* The locale object is instantiated at server launch, but the texts are only loaded when needed.
*
* @author Tastybento
* @author Poslovitch
*/
public class BSBLocale {
final static String LOCALE_FOLDER = "locales";
private BSkyBlock plugin;
private String localeID;
private FileConfiguration locale = null;
private File localeFile = null;
private Locale localeObject;
private String localeId;
private ResourceBundle rb;
Locale localeObject;
/**
* Creates a locale object full of localized string for a language
* Provides localization
* Locale files are .yml and have the filename "bsb_[country and language tag].yml", e.g. bsb_en_GB.yml
* @param plugin
* @param localeName - name of the yaml file that will be used
* @throws MalformedURLException
*/
public BSBLocale(BSkyBlock plugin, String localeID){
public BSBLocale(BSkyBlock plugin, String localeId) throws MalformedURLException {
this.plugin = plugin;
this.localeID = localeID;
getLocale(localeID);
localeObject = new Locale(localeID.substring(0, 2), localeID.substring(3, 5));
this.localeId = localeId;
// Check if the folder exists
File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER);
if (!localeDir.exists()) {
localeDir.mkdirs();
}
// Check if this file does not exist
File localeFile = new File(localeDir, localeId);
if (!localeFile.exists()) {
// Does not exist - look in JAR and save if possible
plugin.saveResource(LOCALE_FOLDER + localeId, false);
}
String languageTag = localeId.substring(4, localeId.length() - 4).replace('_', '-');
URL[] urls = {localeDir.toURI().toURL()};
ClassLoader loader = new URLClassLoader(urls);
localeObject = Locale.forLanguageTag(languageTag);
rb = ResourceBundle.getBundle("bsb", localeObject, loader, YamlResourceBundle.Control.INSTANCE);
}
/**
* Get text from the yml file for this locale
* @param reference - the YAML node where the text is
* @return Text for this locale reference or "" if the locale or the reference do not exist
*/
public String get(String reference) {
// TODO: add placeholder conversion?
if (rb.containsKey(reference)) {
return ChatColor.translateAlternateColorCodes('&', rb.getString(reference));
} else if (!Settings.defaultLanguage.equals(localeId)){
// Try default lang
return plugin.getLocale().get(reference);
}
return "";
}
/**
@ -62,57 +86,8 @@ public class BSBLocale {
* Returns the locale identifier (e.g: en-GB)
* @return the locale ID
*/
public String getLocaleID(){
return this.localeID;
}
/**
* Returns the locale FileConfiguration
* @param localeID - name of the yaml file to get
* @return the FileConfiguration locale object
*/
private FileConfiguration getLocale(String localeID){
if(locale == null){
reloadLocale(localeID);
}
return locale;
}
/**
* Reloads the locale file
* @param localeID - name of the yaml file to reload
*/
private void reloadLocale(String localeID){
// Make directory if it doesn't exist
File directory = new File(plugin.getDataFolder() + File.separator + "locales");
if(!directory.exists()) directory.mkdirs();
if(localeFile == null) localeFile = new File(directory.getPath(), localeID + ".yml");
if(localeFile.exists()){
locale = YamlConfiguration.loadConfiguration(localeFile);
} else {
// Look for defaults in the jars
if(plugin.getResource("locales/" + localeID + ".yml") != null){
plugin.saveResource("locales/" + localeID + ".yml", true);
localeFile = new File(directory.getPath(), localeID + ".yml");
locale = YamlConfiguration.loadConfiguration(localeFile);
} else {
plugin.getLogger().severe("Could not find locale file '" + localeID + "' !");
}
}
}
/* Localization */
private HashMap<String, String> localization = new HashMap<String, String>();
public String get(String id){
// If the text isn't loaded, load it.
if(!localization.containsKey(id)){
// Save the text to the HashMap.
// If the text doesn't exist in the locale file, save it as its id, to help debug.
localization.put(id, locale.getString(id, id));
}
return localization.get(id);
public String getLocaleId(){
return this.localeObject.toLanguageTag();
}
}

View File

@ -0,0 +1,181 @@
/*
* https://github.com/akihyro/yaml-resource-bundle
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package us.tastybento.bskyblock.config;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.AbstractMap.SimpleImmutableEntry;
import static java.util.Arrays.asList;
import static java.util.Collections.enumeration;
import static java.util.Collections.unmodifiableList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.stream.Collectors.toMap;
import java.util.stream.Stream;
import org.yaml.snakeyaml.Yaml;
/**
* {@link ResourceBundle} for YAML format.
*/
public class YamlResourceBundle extends ResourceBundle {
/**
* Entries.
*/
private final Map<String, Object> entries;
/**
* Constructor.
*
* @param string YAML data.
*/
public YamlResourceBundle(String string) {
entries = flattenYamlTree(new Yaml().loadAs(string, Map.class));
}
/**
* Constructor.
*
* @param stream YAML data as input stream.
*/
public YamlResourceBundle(InputStream stream) {
entries = flattenYamlTree(new Yaml().loadAs(stream, Map.class));
}
/**
* Constructor.
*
* @param reader YAML data as input character stream.
*/
public YamlResourceBundle(Reader reader) {
entries = flattenYamlTree(new Yaml().loadAs(reader, Map.class));
}
/**
* Flatten yaml tree structure.
*
* @param map {@link Map} of yaml tree.
* @return {@link Map} of entries.
*/
private static Map<String, Object> flattenYamlTree(Map<?, ?> map) {
return map.entrySet().stream()
.flatMap(YamlResourceBundle::flattenYamlTree)
.collect(toMap(
e -> e.getKey(),
e -> e.getValue(),
(oldValue, newValue) -> newValue
));
}
/**
* Flatten yaml tree structure.
*
* @param entry {@link Entry} of yaml tree.
* @return {@link Stream} of entries.
*/
private static Stream<Entry<String, Object>> flattenYamlTree(Entry<?, ?> entry) {
String key = entry.getKey().toString();
Object value = entry.getValue();
if (value instanceof Map) {
Map<?, ?> valueAsMap = (Map<?, ?>) value;
return valueAsMap.entrySet().stream()
.flatMap(YamlResourceBundle::flattenYamlTree)
.map(e -> new SimpleImmutableEntry<>(key + "." + e.getKey(), e.getValue()));
} else if (value instanceof List) {
List<?> valueAsList = (List<?>) value;
value = valueAsList.stream().toArray(String[]::new);
AtomicInteger index = new AtomicInteger();
return Stream.concat(
Stream.of(new SimpleImmutableEntry<>(key, value)),
valueAsList.stream()
.map(v -> new SimpleImmutableEntry<>(key + "[" + index.getAndIncrement() + "]", v))
);
}
return Stream.of(new SimpleImmutableEntry<>(key, value));
}
/** {@inheritDoc} */
@Override
protected Set<String> handleKeySet() {
return entries.keySet();
}
/** {@inheritDoc} */
@Override
public Enumeration<String> getKeys() {
return enumeration(keySet());
}
/** {@inheritDoc} */
@Override
protected Object handleGetObject(String key) {
return entries.get(key);
}
/**
* {@link ResourceBundle.Control} for YAML format.
*/
public static class Control extends ResourceBundle.Control {
/**
* Singleton instance.
*/
public static final Control INSTANCE = new Control();
/**
* Constructor.
*/
protected Control() {
}
/** {@inheritDoc} */
@Override
public List<String> getFormats(String baseName) {
return unmodifiableList(asList("yaml", "yml"));
}
/** {@inheritDoc} */
@Override
public ResourceBundle newBundle(String baseName,
Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
if (!getFormats(baseName).contains(format)) {
return null;
}
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, format);
InputStream stream = loader.getResourceAsStream(resourceName);
try {
return new YamlResourceBundle(stream);
} finally {
if (stream != null) {
stream.close();
}
}
}
}
}

View File

@ -416,7 +416,7 @@ public class IslandsManager {
player.teleport(home);
//player.sendBlockChange(home, Material.GLOWSTONE, (byte)0);
if (number ==1 ) {
Util.sendMessage(player, ChatColor.GREEN + "Teleported");
Util.sendMessage(player, ChatColor.GREEN + plugin.getLocale(player.getUniqueId()).get("island.teleport").replace("[label]", Settings.ISLANDCOMMAND));
} else {
Util.sendMessage(player, ChatColor.GREEN + "teleported to #" + number);
}

View File

@ -47,6 +47,9 @@ public class Island extends DataObject {
* @author Tastybento
*/
public enum SettingsFlag{
ACID_DAMAGE,
// Can use Anvil
ANVIL,

View File

@ -1,8 +1,17 @@
package us.tastybento.bskyblock.util;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.bukkit.plugin.java.JavaPlugin;
import us.tastybento.bskyblock.BSkyBlock;
@ -12,18 +21,124 @@ import us.tastybento.bskyblock.BSkyBlock;
*/
public class FileLister{
private BSkyBlock plugin;
public FileLister(BSkyBlock plugin){
this.plugin = plugin;
}
public List<File> list(String folderPath, boolean checkJar){
List<File> result = new ArrayList<File>();
File folder = new File(plugin.getDataFolder(), folderPath);
if(folder.exists()){
/**
* Returns a list of yml files in the folder given. If the folder does not exist in the file system
* it can check the plugin jar instead.
* @param folderPath
* @param checkJar - if true, the jar will be checked
* @return List of file names
* @throws IOException
*/
public List<String> list(String folderPath, boolean checkJar) throws IOException {
List<String> result = new ArrayList<String>();
// Check if the folder exists
File localeDir = new File(plugin.getDataFolder(), folderPath);
if (localeDir.exists()) {
FilenameFilter ymlFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
String lowercaseName = name.toLowerCase();
//plugin.getLogger().info("DEBUG: filename = " + name);
if (lowercaseName.endsWith(".yml")) {
return true;
} else {
return false;
}
}
};
return Arrays.asList(localeDir.list(ymlFilter));
} else if (checkJar) {
// Else look in the JAR
File jarfile = null;
/**
* Get the jar file from the plugin.
*/
try {
Method method = JavaPlugin.class.getDeclaredMethod("getFile");
method.setAccessible(true);
jarfile = (File) method.invoke(this.plugin);
} catch (Exception e) {
throw new IOException(e);
}
JarFile jar = new JarFile(jarfile);
/**
* Loop through all the entries.
*/
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String path = entry.getName();
/**
* Not in the folder.
*/
if (!path.startsWith(folderPath)) {
continue;
}
//plugin.getLogger().info("DEBUG: jar filename = " + entry.getName());
if (entry.getName().endsWith(".yml")) {
result.add(entry.getName());
}
}
jar.close();
}
return result;
}
public List<String> listJar(String folderPath) throws IOException {
List<String> result = new ArrayList<String>();
// Look in the JAR
File jarfile = null;
/**
* Get the jar file from the plugin.
*/
try {
Method method = JavaPlugin.class.getDeclaredMethod("getFile");
method.setAccessible(true);
jarfile = (File) method.invoke(this.plugin);
} catch (Exception e) {
throw new IOException(e);
}
JarFile jar = new JarFile(jarfile);
/**
* Loop through all the entries.
*/
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String path = entry.getName();
/**
* Not in the folder.
*/
if (!path.startsWith(folderPath)) {
continue;
}
//plugin.getLogger().info("DEBUG: jar filename = " + entry.getName());
if (entry.getName().endsWith(".yml")) {
result.add(entry.getName());
}
}
jar.close();
return result;
}
}