/* * config.cpp * Handles config options for the entire mud * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute is granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ //#include "os.h" #include "mud.h" #include "bans.h" #include "factions.h" #include "guilds.h" #include "calendar.h" //#include "config.h" // Globals Config *gConfig = NULL; // Static initialization Config* Config::myInstance = NULL; Config::Config() { reset(); inUse = true; } Config::~Config() { if(inUse) throw new bstring("Error, trying to destroy config\n"); else printf("Properly deconstructing Config class"); } //-------------------------------------------------------------------- // Instance Functions //******************************************************************** // Get Instance - Return the static instance of config //******************************************************************** Config* Config::getInstance() { if(myInstance == NULL) myInstance = new Config; return(myInstance); } //******************************************************************** // Destroy Instance - Destroy the static instance //******************************************************************** void Config::destroyInstance() { if(myInstance != NULL) { myInstance->cleanUp(); delete myInstance; } myInstance = NULL; } // End - Instance Functions //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Memory Functions void Config::cleanUp() { clearClans(); clearGuildList(); clearBanList(); clearFactionList(); clearSkills(); calendar->clear(); clearShips(); clearClasses(); clearRaces(); clearRecipes(); clearDeities(); clearAreas(); clearStartLoc(); clearLimited(); clearProperties(); clearCatRefInfo(); clearQuests(); clearAlchemy(); clearCommands(); inUse = false; } //******************************************************************** // resetConfig //******************************************************************** // Sets all config options to their default value. void Config::reset() { roomHead = roomTail = monsterHead = monsterTail = objectHead = objectTail = 0; // These options default to true logSuicide = true; checkDouble = true; getHostByName = true; saveOnDrop = true; logDeath = true; // These options default to false conjureDisabled = false; lessExpLoss = false; pkillInCombatDisabled = false; autoShutdown = false; recordAll = false; charCreationDisabled = false; // Numerical defaults crashes = 0; supportRequiredForGuild = 2; minBroadcastLevel = 2; maxGuilds = 8; numGuilds = 0; dmPass = "default_dm_pw"; webserver = qs = userAgent = ""; lotteryEnabled = true; lotteryTicketPrice = 100; lotteryTicketsSold = 0; lotteryJackpot = 500000; lotteryWon = 0; lotteryWinnings = 0; lotteryRunTime = 0; lotteryNumbers[0] = lotteryNumbers[1] = lotteryNumbers[2] = lotteryNumbers[3] = lotteryNumbers[4] = lotteryNumbers[5] = 0; lotteryCycle = 1; if(!bHavePort) portNum = 3333; calendar = NULL; foreach(LottoTicket* ticket, tickets) { delete ticket; } tickets.clear(); defaultArea = "oceancrest"; movingRoom = roomSearchFailure = doAprilFools = txtOnCrash = someoneFishing = false; flashPolicyPort = 0; memset(customColors, CUSTOM_COLOR_DEFAULT, sizeof(customColors)); customColors[CUSTOM_COLOR_SIZE-1] = 0; customColors[CUSTOM_COLOR_BROADCAST] = 'x'; customColors[CUSTOM_COLOR_GOSSIP] = 'M'; customColors[CUSTOM_COLOR_PTEST] = 'Y'; customColors[CUSTOM_COLOR_NEWBIE] = 'M'; customColors[CUSTOM_COLOR_DM] = 'g'; customColors[CUSTOM_COLOR_ADMIN] = 'g'; customColors[CUSTOM_COLOR_SEND] = 'Y'; customColors[CUSTOM_COLOR_MESSAGE] = 'G'; customColors[CUSTOM_COLOR_WATCHER] = 'C'; customColors[CUSTOM_COLOR_CLASS] = 'y'; customColors[CUSTOM_COLOR_RACE] = 'c'; customColors[CUSTOM_COLOR_CLAN] = 'm'; customColors[CUSTOM_COLOR_TELL] = 'x'; customColors[CUSTOM_COLOR_GROUP] = 'g'; customColors[CUSTOM_COLOR_DAMAGE] = 'm'; customColors[CUSTOM_COLOR_SELF] = 'w'; customColors[CUSTOM_COLOR_GUILD] = 'g'; shopNumObjects = shopNumLines = 0; } bool Config::load() { printf("Initializing command table ...%s.\n", initCommands() ? "done" : "failed"); printf("Loading Config...%s.\n", loadConfig() ? "done" : "failed"); printf("Loading Recipes...%s.\n", loadRecipes() ? "done" : "failed"); printf("Loading Flags...%s.\n", loadFlags() ? "done" : "failed"); printf("Saving Spells...%s.\n", saveSpells() ? "done" : "failed"); printf("Loading Spell List...%s.\n", loadSpellList() ? "done" : "failed"); printf("Loading Quest Table...%s.\n", loadQuestTable() ? "done" : "failed"); printf("Loading New Quests...%s.\n", loadQuests() ? "done" : "failed"); printf("Loading StartLocs...%s.\n", loadStartLoc() ? "done" : "failed"); printf("Loading Properties...%s.\n", loadProperties() ? "done" : "failed"); printf("Loading CatRefInfo...%s.\n", loadCatRefInfo() ? "done" : "failed"); printf("Loading Bans...%s.\n", loadBans() ? "done" : "failed"); printf("Loading Fishing...%s.\n", loadFishing() ? "done" : "failed"); printf("Loading Guilds...%s.\n", loadGuilds() ? "done" : "failed"); printf("Loading Skills...%s.\n", loadSkills() ? "done" : "failed"); printf("Loading Deities...%s.\n", loadDeities() ? "done" : "failed"); printf("Loading Clans...%s.\n", loadClans() ? "done" : "failed"); printf("Loading Classes...%s.\n", loadClasses() ? "done" : "failed"); printf("Loading Races...%s.\n", loadRaces() ? "done" : "failed"); printf("Loading Factions...%s.\n", loadFactions() ? "done" : "failed"); printf("Loading Alchemy...%s.\n", loadAlchemy() ? "done" : "failed"); printf("Loading Limited Items...%s.\n", loadLimited() ? "done" : "failed"); printf("Loading Double Log Info...%s.\n", loadDoubleLog() ? "done" : "failed"); printf("Loading Calendar..."); loadCalendar(); printf("done.\n"); printf("Loading Areas...%s.\n", loadAreas() ? "done" : "failed"); printf("Loading Ships...%s.\n", loadShips() ? "done" : "failed"); return(true); } bool Config::startFlashPolicy() const { return(false); char script[256], policy[256], cmd[256]; if(!flashPolicyPort) { broadcast(isDm, "^oNo flash policy port specified."); return(false); } if(flashPolicyPort == portNum) { broadcast(isDm, "^oFlash policy port equals main mud port."); return(false); } sprintf(script, "%sflashpolicyd.py", BINPATH); if(!file_exists(script)) { broadcast(isDm, "^oUnable to find flash policy server."); return(false); } sprintf(policy, "%sflashpolicy.xml", CONFPATH); if(!file_exists(policy)) { broadcast(isDm, "^oUnable to find flash policy file."); return(false); } if(!fork()) { sprintf(cmd, "python %s --file=%s --port=%d", script, policy, flashPolicyPort); system(cmd); exit(0); } return(true); } bool Config::loadConfig() { char filename[256]; xmlDocPtr xmlDoc; xmlNodePtr rootNode; xmlNodePtr curNode; sprintf(filename, "%s/config.xml", CONFPATH); if(!file_exists(filename)) return(false); if((xmlDoc = xml::loadFile(filename, "Config")) == NULL) return(false); rootNode = xmlDocGetRootElement(xmlDoc); curNode = rootNode->children; // Reset current config reset(); while(curNode) { if(NODE_NAME(curNode, "General")) loadGeneral(curNode); else if(NODE_NAME(curNode, "Lottery")) loadLottery(curNode); curNode = curNode->next; } xmlFreeDoc(xmlDoc); xmlCleanupParser(); return(true); } void Config::loadGeneral(xmlNodePtr rootNode) { xmlNodePtr curNode = rootNode->children; while(curNode) { if(NODE_NAME(curNode, "AutoShutdown")) xml::copyToBool(autoShutdown, curNode); else if(NODE_NAME(curNode, "AprilFools")) xml::copyToBool(doAprilFools, curNode); else if(NODE_NAME(curNode, "FlashPolicyPort")) xml::copyToNum(flashPolicyPort, curNode); else if(NODE_NAME(curNode, "CharCreationDisabled")) xml::copyToBool(charCreationDisabled, curNode); else if(NODE_NAME(curNode, "CheckDouble")) xml::copyToBool(checkDouble, curNode); else if(NODE_NAME(curNode, "GetHostByName")) xml::copyToBool(getHostByName, curNode); else if(NODE_NAME(curNode, "LessExpLoss")) xml::copyToBool(lessExpLoss, curNode); else if(NODE_NAME(curNode, "LogDeath")) xml::copyToBool(logDeath, curNode); else if(NODE_NAME(curNode, "PkillInCombatDisabled")) xml::copyToBool(pkillInCombatDisabled, curNode); else if(NODE_NAME(curNode, "RecordAll")) xml::copyToBool(recordAll, curNode); else if(NODE_NAME(curNode, "LogSuicide")) xml::copyToBool(logSuicide, curNode); else if(NODE_NAME(curNode, "SaveOnDrop")) xml::copyToBool(saveOnDrop, curNode); else if(NODE_NAME(curNode, "MaxGuild")) xml::copyToNum(maxGuilds, curNode); else if(NODE_NAME(curNode, "DmPass")) xml::copyToBString(dmPass, curNode); else if(NODE_NAME(curNode, "Webserver")) xml::copyToBString(webserver, curNode); else if(NODE_NAME(curNode, "QS")) xml::copyToBString(qs, curNode); else if(NODE_NAME(curNode, "UserAgent")) xml::copyToBString(userAgent, curNode); else if(NODE_NAME(curNode, "ShopNumObjects")) xml::copyToNum(shopNumObjects, curNode); else if(NODE_NAME(curNode, "ShopNumLines")) xml::copyToNum(shopNumLines, curNode); else if(NODE_NAME(curNode, "CustomColors")) xml::copyToCString(customColors, curNode); else if(!bHavePort && NODE_NAME(curNode, "Port")) xml::copyToNum(portNum, curNode); curNode = curNode->next; } } void Config::loadLottery(xmlNodePtr rootNode) { xmlNodePtr curNode = rootNode->children; while(curNode) { if(NODE_NAME(curNode, "Enabled")) xml::copyToBool(lotteryEnabled, curNode); else if(NODE_NAME(curNode, "curNoderentCycle")) xml::copyToNum(lotteryCycle, curNode); else if(NODE_NAME(curNode, "curNoderentJackpot")) xml::copyToNum(lotteryJackpot, curNode); else if(NODE_NAME(curNode, "TicketPrice")) xml::copyToNum(lotteryTicketPrice, curNode); else if(NODE_NAME(curNode, "LotteryWon")) xml::copyToBool(lotteryWon, curNode); else if(NODE_NAME(curNode, "TicketsSold")) xml::copyToNum(lotteryTicketsSold, curNode); else if(NODE_NAME(curNode, "WinningsThisCycle")) xml::copyToNum(lotteryWinnings, curNode); else if(NODE_NAME(curNode, "LotteryRunTime")) xml::copyToNum(lotteryRunTime, curNode); else if(NODE_NAME(curNode, "WinningNumbers")) { xml::loadNumArray<short>(curNode, lotteryNumbers, "LotteryNum", 6); } else if(NODE_NAME(curNode, "Tickets")) { loadTickets(curNode); } curNode = curNode->next; } } void Config::loadTickets(xmlNodePtr rootNode) { xmlNodePtr curNode = rootNode->children; LottoTicket* ticket=0; while(curNode) { if(NODE_NAME(curNode, "Ticket")) { if((ticket = new LottoTicket(curNode)) != NULL) { tickets.push_back(ticket); } } curNode = curNode->next; } } unsigned long Config::expNeeded(int level) { if(level < 1) return(0); if(level > MAXALVL) return(MAXINT); return(needed_exp[level-1]); } bool Config::save() const { saveConfig(); return(true); } // Functions to get configured options bool Config::saveConfig() const { xmlDocPtr xmlDoc; xmlNodePtr rootNode, curNode; char filename[256]; xmlDoc = xmlNewDoc(BAD_CAST "1.0"); rootNode = xmlNewDocNode(xmlDoc, NULL, BAD_CAST "Config", NULL); xmlDocSetRootElement(xmlDoc, rootNode); // Make general section curNode = xmlNewChild(rootNode, NULL, BAD_CAST "General", NULL); if(!bHavePort) xml::saveNonZeroNum(curNode, "Port", portNum); xml::saveNonNullString(curNode, "DmPass", dmPass); xml::saveNonNullString(curNode, "Webserver", webserver); xml::saveNonNullString(curNode, "QS", qs); xml::saveNonNullString(curNode, "UserAgent", userAgent); xml::saveNonNullString(curNode, "CustomColors", customColors); xml::newBoolChild(curNode, "AprilFools", doAprilFools); xml::saveNonZeroNum(curNode, "FlashPolicyPort", flashPolicyPort); xml::newBoolChild(curNode, "AutoShutdown", autoShutdown); xml::newBoolChild(curNode, "CharCreationDisabled", charCreationDisabled); xml::newBoolChild(curNode, "CheckDouble", checkDouble); xml::newBoolChild(curNode, "GetHostByName", getHostByName); xml::newBoolChild(curNode, "LessExpLoss", lessExpLoss); xml::newBoolChild(curNode, "LogDeath", logDeath); xml::newBoolChild(curNode, "PkillInCombatDisabled", pkillInCombatDisabled); xml::newBoolChild(curNode, "RecordAll", recordAll); xml::newBoolChild(curNode, "LogSuicide", logSuicide); xml::newBoolChild(curNode, "SaveOnDrop", saveOnDrop); xml::newBoolChild(curNode, "MaxGuild", maxGuilds); xml::saveNonZeroNum(curNode, "ShopNumObjects", shopNumObjects); xml::saveNonZeroNum(curNode, "ShopNumLines", shopNumLines); // Lottery Section curNode = xmlNewChild(rootNode, NULL, BAD_CAST "Lottery", NULL); xml::saveNonZeroNum(curNode, "CurrentCycle", lotteryCycle); xml::saveNonZeroNum(curNode, "CurrentJackpot", lotteryJackpot); xml::newBoolChild(curNode, "Enabled", BAD_CAST iToYesNo(lotteryEnabled)); xml::saveNonZeroNum(curNode, "TicketPrice", lotteryTicketPrice); xml::saveNonZeroNum(curNode, "TicketsSold", lotteryTicketsSold); xml::saveNonZeroNum(curNode, "LotteryWon", lotteryWon); xml::saveNonZeroNum(curNode, "WinningsThisCycle", lotteryWinnings); xml::saveNonZeroNum(curNode, "LotteryRunTime", lotteryRunTime); saveShortIntArray(curNode, "WinningNumbers", "LotteryNum", lotteryNumbers, 6); xmlNodePtr ticketsNode = xml::newStringChild(curNode, "Tickets"); foreach(LottoTicket* ticket, tickets) { ticket->saveToXml(ticketsNode); } sprintf(filename, "%s/config.xml", CONFPATH); xml::saveFile(filename, xmlDoc); xmlFreeDoc(xmlDoc); return(true); } int Config::getPortNum() const { return(portNum); } void Config::setPortNum(int pPort) { portNum = pPort; } int getPkillInCombatDisabled() { return(gConfig->pkillInCombatDisabled); } bstring Config::getMonthDay() const { long t = time(0); bstring str = ctime(&t); return(str.substr(4,6)); } bool Config::isAprilFools() const { return(doAprilFools && getMonthDay() == "Apr 1"); } bool Config::willAprilFools() const { return(doAprilFools); } int Config::getFlashPolicyPort() const { return(flashPolicyPort); } bool Config::sendTxtOnCrash() const { return(txtOnCrash); } void Config::toggleTxtOnCrash() { txtOnCrash = !txtOnCrash; } int Config::getShopNumObjects() const { return(shopNumObjects ? shopNumObjects : 400); } int Config::getShopNumLines() const { return(shopNumLines ? shopNumLines : 150); } const cWeather* Config::getWeather() const { return(calendar->getCurSeason()->getWeather()); } bstring Config::getDmPass() const { return(dmPass); } bstring Config::getWebserver() const { return(webserver); } bstring Config::getQS() const { return(qs); } bstring Config::getUserAgent() const { return(userAgent); } #include "specials.h" bstring Config::getSpecialFlag(int index) { if(index >= SA_MAX_FLAG || index <= SA_NO_FLAG ) return("Invalid Flag"); return(specialFlags[index].name); } #include "version.h" bstring Config::getVersion() { return(VERSION); } // End Config Functions //--------------------------------------------------------------------