/* ExtraHardMode Server Plugin for Minecraft Copyright (C) 2012 Ryan Hamshire This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package me.ryanhamshire.ExtraHardMode; import java.io.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; //singleton class which manages all ExtraHardMode data (except for config options) public class DataStore { //in-memory cache for messages private String [] messages; //path information, for where stuff stored on disk is well... stored protected final static String dataLayerFolderPath = "plugins" + File.separator + "ExtraHardModeData"; final static String configFilePath = dataLayerFolderPath + File.separator + "config.yml"; final static String messagesFilePath = dataLayerFolderPath + File.separator + "messages.yml"; //in-memory cache for player data private ConcurrentHashMap<String, PlayerData> playerNameToPlayerDataMap = new ConcurrentHashMap<String, PlayerData>(); public DataStore() { this.initialize(); } //initialization! void initialize() { //load up all the messages from messages.yml this.loadMessages(); } private void loadMessages() { Messages [] messageIDs = Messages.values(); this.messages = new String[Messages.values().length]; HashMap<String, CustomizableMessage> defaults = new HashMap<String, CustomizableMessage>(); //initialize defaults this.addDefault(defaults, Messages.NoTorchesHere, "There's not enough air flow down here for permanent flames. Use another method to light your way.", null); this.addDefault(defaults, Messages.StoneMiningHelp, "You'll need an iron or diamond pickaxe to break stone. Try exploring natural formations for exposed ore like coal, which softens stone around it when broken.", null); this.addDefault(defaults, Messages.NoPlacingOreAgainstStone, "Sorry, you can't place ore next to stone.", null); this.addDefault(defaults, Messages.RealisticBuilding, "You can't build while in the air.", null); this.addDefault(defaults, Messages.LimitedTorchPlacements, "It's too soft there to fasten a torch.", null); this.addDefault(defaults, Messages.NoCraftingMelonSeeds, "That appears to be seedless!", null); this.addDefault(defaults, Messages.LimitedEndBuilding, "Sorry, building here is very limited. You may only break blocks to reach ground level.", null); this.addDefault(defaults, Messages.DragonFountainTip, "Congratulations on defeating the dragon! If you can't reach the fountain to jump into the portal, throw an ender pearl at it.", null); this.addDefault(defaults, Messages.NoSwimmingInArmor, "You're carrying too much weight to swim!", null); //load the config file FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); //for each message ID for(int i = 0; i < messageIDs.length; i++) { //get default for this message Messages messageID = messageIDs[i]; CustomizableMessage messageData = defaults.get(messageID.name()); //if default is missing, log an error and use some fake data for now so that the plugin can run if(messageData == null) { ExtraHardMode.AddLogEntry("Missing message for " + messageID.name() + ". Please contact the developer."); messageData = new CustomizableMessage(messageID, "Missing message! ID: " + messageID.name() + ". Please contact a server admin.", null); } //read the message from the file, use default if necessary this.messages[messageID.ordinal()] = config.getString("Messages." + messageID.name() + ".Text", messageData.text); config.set("Messages." + messageID.name() + ".Text", this.messages[messageID.ordinal()]); if(messageData.notes != null) { messageData.notes = config.getString("Messages." + messageID.name() + ".Notes", messageData.notes); config.set("Messages." + messageID.name() + ".Notes", messageData.notes); } } //save any changes try { config.save(DataStore.messagesFilePath); } catch(IOException exception) { ExtraHardMode.AddLogEntry("Unable to write to the configuration file at \"" + DataStore.messagesFilePath + "\""); } defaults.clear(); System.gc(); } private void addDefault(HashMap<String, CustomizableMessage> defaults, Messages id, String text, String notes) { CustomizableMessage message = new CustomizableMessage(id, text, notes); defaults.put(id.name(), message); } synchronized public String getMessage(Messages messageID, String... args) { String message = messages[messageID.ordinal()]; for(int i = 0; i < args.length; i++) { String param = args[i]; message = message.replace("{" + i + "}", param); } return message; } //retrieves player data from memory synchronized public PlayerData getPlayerData(String playerName) { //first, look in memory PlayerData playerData = this.playerNameToPlayerDataMap.get(playerName); //if not there, create a fresh entry if(playerData == null) { playerData = new PlayerData(); this.playerNameToPlayerDataMap.put(playerName, playerData); } //try the hash map again. if it's STILL not there, we have a bug to fix return this.playerNameToPlayerDataMap.get(playerName); } }