#include "uox3.h" #include "cServerDefinitions.h" #include "ssection.h" #include "scriptc.h" #include "StringUtility.hpp" #include #include #include using namespace std::string_literals; CServerDefinitions *FileLookup; //================================================================================================== auto CurrentWorkingDir() -> std::string { return std::filesystem::current_path().string(); } //================================================================================================== auto BuildPath( const std::string &extra ) -> std::string { auto temp = std::filesystem::current_path(); temp /= std::filesystem::path( extra ); return temp.string(); } //================================================================================================== auto ShortDirectory( std::string sPath ) -> std::string { return std::filesystem::path( sPath ).filename().string(); } //================================================================================================== const std::array dirNames { "items"s, "npc"s, "create"s, "regions"s, "misc"s, "skills"s, "location"s, "menus"s, "spells"s, "newbie"s, "titles"s, "advance"s, "house"s, "colors"s, "spawn"s, "html"s, "race"s, "weather"s, "harditems"s, "command"s, "msgboard"s, "carve"s, "creatures"s, "maps"s }; std::multimap g_mmapAddMenuMap; //================================================================================================== CServerDefinitions::CServerDefinitions() : defaultPriority( 0 ) { } //================================================================================================== auto CServerDefinitions::Startup() -> void { Console.PrintSectionBegin(); Console << "Loading server scripts..." << myendl; Console << " o Clearing AddMenuMap entries(" << static_cast( g_mmapAddMenuMap.size() ) << ")" << myendl; g_mmapAddMenuMap.clear(); ScriptListings.resize( NUM_DEFS ); ReloadScriptObjects(); Console.PrintSectionBegin(); } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::Reload() //| Date - 04/17/2002 //o------------------------------------------------------------------------------------------------o //| Purpose - Reload the dfn files. //| Changes - 04042004 - Added the code to clear out the //| Auto-AddMenu items so there isn't any duplication in the //| multimap //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::Reload() -> bool { // We need to clear out the AddMenuItem Map g_mmapAddMenuMap.clear(); // Cleanup(); ScriptListings.clear(); ScriptListings.resize( NUM_DEFS ); ReloadScriptObjects(); return true; } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::Reload( DEFINITIONCATEGORIES toReload ) //o------------------------------------------------------------------------------------------------o //| Purpose - Reload a specific set of dfn files. //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::Reload( DEFINITIONCATEGORIES toReload ) -> bool { Dispose( toReload ); LoadDFNCategory( toReload ); return true; } //================================================================================================== auto CServerDefinitions::Cleanup() -> void { std::vector::iterator slIter; for( slIter = ScriptListings.begin(); slIter != ScriptListings.end(); ++slIter ) { VECSCRIPTLIST& toDel = ( *slIter ); for( size_t j = 0; j < toDel.size(); ++j ) { if( toDel[j] ) { delete toDel[j]; toDel[j] = nullptr; } } } } //================================================================================================== CServerDefinitions::~CServerDefinitions() { Cleanup(); } //================================================================================================== auto CServerDefinitions::Dispose( DEFINITIONCATEGORIES toDispose ) -> bool { bool retVal = false; if( toDispose != NUM_DEFS ) { VECSCRIPTLIST& toDel = ScriptListings[toDispose]; for( VECSCRIPTLIST_CITERATOR dIter = toDel.begin(); dIter != toDel.end(); ++dIter ) { Script *toDelete = ( *dIter ); if( toDelete ) { retVal = true; delete toDelete; } } toDel.clear(); } return retVal; } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::FindEntry //o------------------------------------------------------------------------------------------------o //| Purpose - Find a specific CScriptSection from the DFNs in memory //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::FindEntry( const std::string &toFind, DEFINITIONCATEGORIES typeToFind ) ->CScriptSection * { CScriptSection *rValue = nullptr; if( !toFind.empty() && typeToFind != NUM_DEFS ) { auto tUFind = oldstrutil::upper( toFind ); VECSCRIPTLIST& toDel = ScriptListings[typeToFind]; for( VECSCRIPTLIST_CITERATOR dIter = toDel.begin(); dIter != toDel.end(); ++dIter ) { Script *toCheck = ( *dIter ); if( toCheck ) { rValue = toCheck->FindEntry( tUFind ); if( rValue ) { break; } } } } return rValue; } //================================================================================================== auto CServerDefinitions::FindEntrySubStr( const std::string &toFind, DEFINITIONCATEGORIES typeToFind ) ->CScriptSection * { CScriptSection *rValue = nullptr; if( !toFind.empty() && typeToFind != NUM_DEFS ) { VECSCRIPTLIST& toDel = ScriptListings[typeToFind]; for( VECSCRIPTLIST_CITERATOR dIter = toDel.begin(); dIter != toDel.end(); ++dIter ) { Script *toCheck = ( *dIter ); if( toCheck ) { rValue = toCheck->FindEntrySubStr( toFind ); if( rValue ) { break; } } } } return rValue; } const std::string defExt = ".dfn"; //================================================================================================== struct PrioScan_st { std::string filename; SI16 priority; PrioScan_st() : filename( "" ), priority( 0 ) { } PrioScan_st( const char *toUse, SI16 mPrio ) : filename( toUse ), priority( mPrio ) { } }; //================================================================================================== inline auto operator == ( const PrioScan_st& x, const PrioScan_st& y ) -> bool { return ( x.priority == y.priority ); } //================================================================================================== inline auto operator < ( const PrioScan_st& x, const PrioScan_st& y ) -> bool { return ( x.priority < y.priority ); } //================================================================================================== inline auto operator > ( const PrioScan_st& x, const PrioScan_st& y ) -> bool { return ( x.priority > y.priority ); } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::LoadDFNCategory //o------------------------------------------------------------------------------------------------o //| Purpose - Load the files found for each DFN category //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::LoadDFNCategory( DEFINITIONCATEGORIES toLoad) -> void { CleanPriorityMap(); defaultPriority = 0; UI08 wasPriod = 2; BuildPriorityMap( toLoad, wasPriod ); CDirectoryListing fileList( toLoad, defExt ); fileList.Flatten( true ); std::vector *shortListing = fileList.FlattenedShortList(); std::vector *longListing = fileList.FlattenedList(); std::vector mSort; for( size_t i = 0; i < shortListing->size(); ++i ) { mSort.push_back( PrioScan_st(( *longListing )[i].c_str(), GetPriority(( *shortListing )[i].c_str() ))); } if( !mSort.empty() ) { std::sort( mSort.begin(), mSort.end() ); Console.Print( oldstrutil::format( "Section %20s : %6i", dirNames[toLoad].c_str(), 0 )); size_t iTotal = 0; Console.TurnYellow(); std::vector::const_iterator mIter; for( mIter = mSort.begin(); mIter != mSort.end(); ++mIter ) { Console.Print( "\b\b\b\b\b\b" ); ScriptListings[toLoad].push_back( new Script(( *mIter ).filename, toLoad, false )); iTotal += ScriptListings[toLoad].back()->NumEntries(); Console.Print( oldstrutil::format( "%6i", iTotal )); } Console.Print( oldstrutil::format( "\b\b\b\b\b\b%6i", CountOfEntries( toLoad ))); Console.TurnNormal(); Console.Print( " entries" ); switch( wasPriod ) { case 0: Console.PrintSpecial( CGREEN, "prioritized" ); break; // prioritized case 1: Console.PrintSpecial( CGREEN, "done" ); break; // file exist, no section default: case 2: Console.PrintSpecial( CBLUE, "done" ); break; // no file }; } } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::ReloadScriptObjects() //o------------------------------------------------------------------------------------------------o //| Purpose - Reload all the various categories of DFN scripts //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::ReloadScriptObjects() -> void { Console << myendl; for( SI32 sCtr = 0; sCtr < NUM_DEFS; ++sCtr ) { LoadDFNCategory( static_cast( sCtr )); } CleanPriorityMap(); } //================================================================================================== auto CServerDefinitions::CountOfEntries( DEFINITIONCATEGORIES typeToFind ) -> size_t { size_t sumEntries = 0; VECSCRIPTLIST *toScan = &( ScriptListings[typeToFind] ); if( toScan ) { for( auto cIter = toScan->begin(); cIter != toScan->end(); ++cIter ) { sumEntries += (*cIter)->NumEntries(); } } return sumEntries; } //================================================================================================== auto CServerDefinitions::CountOfFiles( DEFINITIONCATEGORIES typeToFind ) -> size_t { return ScriptListings[typeToFind].size(); } //================================================================================================== auto CServerDefinitions::FirstScript( DEFINITIONCATEGORIES typeToFind ) -> Script * { Script *retScript = nullptr; slIter = ScriptListings[typeToFind].begin(); if( !FinishedScripts( typeToFind )) { retScript = ( *slIter ); } return retScript; } //================================================================================================== auto CServerDefinitions::NextScript( DEFINITIONCATEGORIES typeToFind ) ->Script * { Script *retScript = nullptr; if( !FinishedScripts( typeToFind )) { ++slIter; if( !FinishedScripts( typeToFind )) { retScript = ( *slIter ); } } return retScript; } //================================================================================================== auto CServerDefinitions::FinishedScripts( DEFINITIONCATEGORIES typeToFind ) -> bool { return ( slIter == ScriptListings[typeToFind].end() ); } //================================================================================================== auto CServerDefinitions::CleanPriorityMap() -> void { priorityMap.clear(); } //o------------------------------------------------------------------------------------------------o //| Function - CServerDefinitions::BuildPriorityMap() //o------------------------------------------------------------------------------------------------o //| Purpose - Build DFN priority map based on entires from priority.nfo //o------------------------------------------------------------------------------------------------o auto CServerDefinitions::BuildPriorityMap( DEFINITIONCATEGORIES category, UI08& wasPrioritized ) -> void { CDirectoryListing priorityFile( category, "priority.nfo", false ); std::vector *longList = priorityFile.List(); if( !longList->empty() ) { std::string filename = ( *longList )[0]; // Do we have any priority informat? if( FileExists( filename )) // the file exists, so perhaps we do { auto prio = std::make_unique