/* ************************************************************************* ArmageTron -- Just another Tron Lightcycle Game in 3D. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) ************************************************************************** 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *************************************************************************** */ #include #include #include #include "tConfiguration.h" #include #include #include #include "tString.h" #include "tToDo.h" #include "tConsole.h" #include "tDirectories.h" bool tConfItemBase::printChange=true; tConfItemBase *tConfItemBase::s_ConfItemAnchor=NULL; bool st_FirstUse=true; static tConfItem fu("FIRST_USE",st_FirstUse); //static tConfItem fu("FIRST_USE","help_first_use",st_FirstUse); tConfItemBase::tConfItemBase(const char *t) :tListItem(s_ConfItemAnchor),id(-1),title(t), changed(false){ tConfItemBase *run = s_ConfItemAnchor; while (run){ if (run != this && !strcmp(t,run->title)) tERR_ERROR_INT("Two tConfItems with the same name " << t << "!"); run = run->Next(); } // compose help name tString helpname; helpname << title << "_help"; for(int i=helpname.Len()-1;i>=0;i--) helpname[i]=tolower(helpname[i]); ((tOutput&)help).AddLocale(helpname); } tConfItemBase::tConfItemBase(const char *t, const tOutput& h) :tListItem(s_ConfItemAnchor),id(-1),title(t), help(h), changed(false){ tConfItemBase *run = s_ConfItemAnchor; while (run){ if (run != this && !strcmp(t,run->title)) tERR_ERROR_INT("Two tConfItems with the same name " << t << "!"); run = run->Next(); } } tConfItemBase::~tConfItemBase(){} void tConfItemBase::SaveAll(std::ostream &s){ for(tConfItemBase *ci = s_ConfItemAnchor; ci ; ci = ci->Next()){ if (ci->Save()){ s << std::setw(28) << ci->title << " "; ci->WriteVal(s); s << "\n"; } } } int tConfItemBase::EatWhitespace(std::istream &s){ int c=' '; while(isspace(c) && c!='\n' && s.good() && !s.eof()) c=s.get(); s.putback(c); return c; } void tConfItemBase::LoadAll(std::istream &s){ int line=0; while(!s.eof() && s.good()){ int i; tString name; s >> name; // make name uppercase: for(i=name.Len()-1;i>=0;i--) name[i]=toupper(name[i]); bool found=false; if (name[0]=='#'){ // comment. ignore rest of line char c=' '; while(c!='\n' && s.good() && !s.eof()) c=s.get(); found=true; } if (strlen(name)==0) // ignore empty lines found=true; for(tConfItemBase *ci=s_ConfItemAnchor;!found && ci; ci = ci->Next()){ if (!strcmp(name,ci->title)){ bool cb=ci->changed; ci->changed=false; ci->ReadVal(s); if (ci->changed) ci->WasChanged(); else ci->changed=cb; found=true; } } if (!found && printChange){ // eat rest of input line tString rest; rest.ReadLine( s ); tOutput o; o.SetTemplateParameter(1, name); o << "$config_command_unknown"; con << o; int sim_maxlen=-1; for(tConfItemBase *ci = s_ConfItemAnchor; ci ; ci = ci->Next()){ if (strstr(ci->title,name) && static_cast(strlen(ci->title)) > sim_maxlen) sim_maxlen=strlen(ci->title); } if (sim_maxlen>0){ con << tOutput("$config_command_other"); for(tConfItemBase *ci = s_ConfItemAnchor; ci ; ci = ci->Next()){ if (strstr(ci->title,name)){ tString mess; mess << ci->title; mess.SetPos( sim_maxlen+2, false ); mess << "("; mess << ci->help; mess << ")\n"; con << mess; } } } else con << '\n'; } line++; } // std::cout << line << " lines read.\n"; } void tConfItemBase::DocAll(std::ostream &s){ for(tConfItemBase *ci = s_ConfItemAnchor; ci ; ci = ci->Next()) { tString line; line << ci->title; line.SetPos( 30, false ); line << ci->help; s << line << "\n"; } } /* void tConfItemBase::ReadVal(std::istream &s); void tConfItemBase::WriteVal(std::istream &s); */ /* tString configfile(){ tString f; //#ifndef WIN32 // f << static_cast(getenv("HOME")); // f << st_LogDir << // f << "/.ArmageTronrc"; //#else const tPath& vpath = tDirectories::Var(); for ( int prio = vpath.MaxPriority(); prio>=0; --prio ) { tString path = vpath.Path( prio ); prio = -1; f << st_LogDir << "/user.cfg"; //#endif return f; } */ static bool Load( const tPath& path, const char* filename ) { if ( !filename ) { return false; } std::ifstream s; if ( path.Open( s, filename ) ) { tConfItemBase::LoadAll( s ); return true; } else { return false; } } void st_LoadConfig() { const tPath& var = tDirectories::Var(); const tPath& config = tDirectories::Config(); const tPath& data = tDirectories::Data(); tConfItemBase::printChange=false; { Load( var, "user.cfg" ); } if (st_FirstUse) { Load( config, "default.cfg" ); } Load( config, "settings.cfg" ); #ifdef DEDICATED Load( config, "settings_dedicated.cfg" ); #endif Load( data, "moviepack/settings.cfg" ); Load( config, "autoexec.cfg" ); Load( var, "autoexec.cfg" ); tConfItemBase::printChange=true; } void st_SaveConfig() { std::ofstream s; if ( tDirectories::Var().Open( s, "user.cfg" ) ) { tConfItemBase::SaveAll(s); } else { tOutput o("$config_file_write_error"); con << o; std::cerr << o; } } void tConfItemLine::ReadVal(std::istream &s){ tString dummy; dummy.ReadLine(s); if(strcmp(dummy,*target)){ if (printChange) { tOutput o; o.SetTemplateParameter(1, title); o.SetTemplateParameter(2, *target); o.SetTemplateParameter(3, dummy); o << "$config_value_changed"; con << o; } *target=dummy; changed=true; } *target=dummy; } void tConfItemLine::WriteVal(std::ostream &s){ tConfItem::WriteVal(s); } tConfItemFunc::tConfItemFunc (const char *title, CONF_FUNC *func) :tConfItemBase(title),f(func){} tConfItemFunc::~tConfItemFunc(){} void tConfItemFunc::ReadVal(std::istream &s){(*f)(s);} void tConfItemFunc::WriteVal(std::ostream &){}; bool tConfItemFunc::Save(){return false;} void Include(std::istream& s) { tString file; s >> file; if ( !Load( tDirectories::Var(), file ) ) { Load( tDirectories::Config(), file ); } } static tConfItemFunc s_Include("INCLUDE", &Include);