/*
* 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
//--------------------------------------------------------------------