// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . //----------------------------------------------------------------------------- // includes //----------------------------------------------------------------------------- //nel #include "nel/misc/command.h" #include "nel/misc/variable.h" // game share #include "game_share/utils.h" #include "game_share/file_description_container.h" #include "game_share/singleton_registry.h" // local #include "em_event_manager.h" //----------------------------------------------------------------------------- // Namespaces //----------------------------------------------------------------------------- using namespace std; using namespace NLMISC; //----------------------------------------------------------------------------- // Variables //----------------------------------------------------------------------------- NLMISC::CVariable ToolsDirectory("EventManager", "EventToolDirectory", "Directory containing event tools", string("./events/tools/"), 0, true); NLMISC::CVariable EventDirectory("EventManager", "EventUserDirectory", "Directory containing event files", string("./events/user/"), 0, true); NLMISC::CVariable LandsDirectory("EventManager", "EventLandDirectory", "Directory containing event files", string("./events/land/"), 0, true); NLMISC::CVariable Shard("EventManager", "ActiveShard", "Shard we are logged into", string(""), 0, true); NLMISC::CVariable Login("EventManager", "ActiveShardLogin", "User name we're logged in under", string(""), 0, true); NLMISC::CVariable EventName("EventManager", "EventName", "Directory containing event files", string(""), 0, true); NLMISC::CVariable ToolsShardName("EventExecutor", "ToolsShardName", "Shard from which tools are to be downloaded", string("ravna"), 0, true); //----------------------------------------------------------------------------- // Static routines for storing variables to / reading from a file //----------------------------------------------------------------------------- const char* variablesFilename= "em_active_event.txt"; static void readVariablesFromFile() { NLMISC::CSString s; if (NLMISC::CFile::fileExists(variablesFilename)) s.readFromFile(variablesFilename); EventName= s.line(0); Shard= s.line(1); Login= s.line(2); } static void writeVariablesToFile() { NLMISC::CSString s; s+= EventName.get()+"\n"; s+= Shard.get()+"\n"; s+= Login.get()+"\n"; s.writeToFile(variablesFilename); } //----------------------------------------------------------------------------- // CContestCtrlScript Commands //----------------------------------------------------------------------------- NLMISC_CATEGORISED_COMMAND(EventManager,emPeek,"display the currently loaded event for a given shard","[]") { CNLSmartLogOverride logOverride(&log); if (args.size()>0) Shard= args[0]; CEventManager::getInstance()->peekInstalledEvent(Shard.get()); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emLogin,"login to an event shard"," ") { CNLSmartLogOverride logOverride(&log); if (args.size()<3) return false; Shard=args[0]; Login=args[1]; writeVariablesToFile(); NLMISC::CSString password; for (uint32 i=2;ilogin(args[0],args[1],password.strip()); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emNewEvent,"create a new event"," ") { CNLSmartLogOverride logOverride(&log); if (args.size()!=2) return false; DROP_IF(args[0]!="fyros" && args[0]!="matis" && args[0]!="tryker" && args[0]!="zorai", "Bad continent name (should be fyros / matis / tryker / zorai): "+args[0], return true); NLMISC::CSString continent= args[0]; EventName= args[1]; writeVariablesToFile(); // make sure an event for this name doesn't already exist DROP_IF(NLMISC::CFile::fileExists(EventDirectory.get()+EventName.get()+".worldedit"), "An event already exists with this name: "+EventName.get(),return true); // create the directory tree as required NLMISC::CFile::createDirectoryTree(EventDirectory.get()+EventName.get()); // build a file description record containing all of the event files in a given directory CFileDescriptionContainer fdc; NLMISC::CVectorSString wildcards; wildcards.push_back("*.ref"); fdc.addFiles(ToolsDirectory.get()+"common"+"/", reinterpret_cast &>(wildcards)); fdc.addFiles(ToolsDirectory.get()+continent+"/", reinterpret_cast &>(wildcards)); // run through the files copying them to the new directory NLMISC::CSString worldEditFile; for (uint32 i=0;idisplayNL("- Creating file: %s",filename.c_str()); // copy the file NLMISC::CSString fileContents; fileContents.readFromFile(fdc[i].FileName.c_str()); fileContents.writeToFile(EventDirectory.get()+EventName.get()+"/"+filename); } // create the world editor file NLMISC::InfoLog->displayNL("- Creating world editor script: %s",(EventName.get()+".worldedit").c_str()); NLMISC::CSString weFile; weFile.readFromFile(ToolsDirectory.get()+continent+"/"+continent+".we_ref"); weFile=weFile.replace("$event$",(EventName.get()).c_str()); weFile=weFile.replace("$tools$",(ToolsDirectory.get()).c_str()); weFile=weFile.replace("$lands$",(LandsDirectory.get()).c_str()); weFile.writeToFile(EventDirectory.get()+EventName.get()+".worldedit"); NLMISC::InfoLog->displayNL("Done."); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emSetEvent,"activate an existing event","") { CNLSmartLogOverride logOverride(&log); if (args.size()!=1) return false; DROP_IF(!NLMISC::CFile::fileExists(EventDirectory.get()+args[0]+".worldedit"), "Event not found: "+args[0],return true); EventName= args[0]; writeVariablesToFile(); return true; } //NLMISC_CATEGORISED_COMMAND(EventManager,emRestartShard,"restart the given event shard","[]") //{ // CNLSmartLogOverride logOverride(&log); // // if (args.size()>0) // Shard= args[0]; // // CEventManager::getInstance()->restartShard(Shard.get()); // // return true; //} NLMISC_CATEGORISED_COMMAND(EventManager,emUpload,"upload an event to a given event shard","[] []") { CNLSmartLogOverride logOverride(&log); if (args.size()>0) EventName= args[0]; if (args.size()>1) Shard= args[1]; // build a file description record containing all of the event files in a given directory CFileDescriptionContainer fdc; NLMISC::CVectorSString wildcards; wildcards.push_back("*.primitive"); wildcards.push_back("*.txt"); wildcards.push_back("*.uxt"); wildcards.push_back("*.gss"); fdc.addFiles(EventDirectory.get()+"/"+EventName.get()+"/", reinterpret_cast &>(wildcards)); // prepare to read the files from disk NLMISC::InfoLog->displayNL("Scanning disk for file list..."); NLMISC::CVectorSString fileBodies; // load up the files and add them to the data block one by one uint32 totalsize=0; for (uint32 i=0;idisplayNL("- Adding file: %s",fdc[i].FileName.c_str()); vectAppend(fileBodies).readFromFile(fdc[i].FileName); DROP_IF(fileBodies.back().size()!=fdc[i].FileSize,"ERROR: Failed to read file: "+fdc[i].FileName,return true); totalsize+= fdc[i].FileSize; } // have the event manager do the uploading... nlinfo("Sending data: %d bytes in %d files",totalsize,fdc.size()); CEventManager::getInstance()->upload(Shard.get(),EventName.get(),fdc,fileBodies); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emUnload,"upload an event to a given event shard","[]") { CNLSmartLogOverride logOverride(&log); if (args.size()>1) return false; if (args.size()>0) Shard= args[0]; // build a file description record containing all of the event files in a given directory CFileDescriptionContainer fdc; NLMISC::CVectorSString fileBodies; // have the event manager do the uploading... nlinfo("Sending empty event data: 0 bytes in 0 files"); CEventManager::getInstance()->upload(Shard.get(),"No Event",fdc,fileBodies); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emEventStart,"start the event running on a given event shard","[]") { CNLSmartLogOverride logOverride(&log); if (args.size()>1) return false; if (args.size()>0) Shard= args[0]; // have the event manager do the work... CEventManager::getInstance()->startEvent(Shard.get()); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emEventStop,"stop the event that is currently running on a given event shard","[]") { CNLSmartLogOverride logOverride(&log); if (args.size()>1) return false; if (args.size()>0) Shard= args[0]; // have the event manager do the work... CEventManager::getInstance()->stopEvent(Shard.get()); return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emUpdateTools,"update tools installed on local PC","") { CNLSmartLogOverride logOverride(&log); if (args.size()!=0) return false; // have the event manager do the work... CEventManager::getInstance()->updateTools(); return true; } //----------------------------------------------------------------------------- // Extra commands that open MFC windows //----------------------------------------------------------------------------- //#ifdef _WINDOWS #if 0 #include "mfc/stdafx.h" #include "nel/misc/win_displayer.h" #include "nel/net/service.h" #include "mfc/enter_name.h" #include "mfc/login_window.h" #include "mfc/select_event_window.h" #include "mfc/upload_window.h" #include "mfc/shard_select_window.h" class CMFCDummy: public IServiceSingleton { public: void init() { AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); static CWinApp App; AfxWinInit(GetModuleHandle(NULL), NULL, GetCommandLine(),0); } }; static CMFCDummy MFCDummy; NLMISC_CATEGORISED_COMMAND(EventManager,emWinLogin,"login to an event shard","") { AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CLoginWindow dlg(&parent); dlg.Shard = Shard; dlg.Login = Login; if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emLogin "+dlg.Shard+" "+dlg.Login+" "+dlg.Password).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinNewEvent,"create a new event","") { AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CEnterName dlg(&parent); dlg.ComboValue= "fyros"; if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emNewEvent "+dlg.ComboValue+" "+dlg.Text).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinSetEvent,"activate an existing event","") { AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CSelectEventWindow dlg(&parent); dlg.Name = "lastName"; if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emSetEvent "+dlg.Name).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinUpload,"upload an event to a given event shard","") { NLMISC::CVectorSString shardNames; CEventManager::getInstance()->getShards(shardNames); DROP_IF(shardNames.empty(),"You must login before you can upload events",return true); AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CUploadWindow dlg(&parent); if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emUpload "+dlg.Event+" "+dlg.Shard).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinUnload,"unload the event on a given event shard","") { NLMISC::CVectorSString shardNames; CEventManager::getInstance()->getShards(shardNames); DROP_IF(shardNames.empty(),"You must login before you can unload events",return true); AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CShardSelectWindow dlg(&parent); if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emUnload "+dlg.ShardName).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinPeek,"display the currently loaded event for a given shard","") { NLMISC::CVectorSString shardNames; CEventManager::getInstance()->getShards(shardNames); DROP_IF(shardNames.empty(),"You must login before you can peek at installed events",return true); AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CShardSelectWindow dlg(&parent); if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emPeek "+dlg.ShardName).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinEventStart,"start the event running on a given event shard","") { NLMISC::CVectorSString shardNames; CEventManager::getInstance()->getShards(shardNames); DROP_IF(shardNames.empty(),"You must login before you can start or stop events",return true); AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CShardSelectWindow dlg(&parent); if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emEventStart "+dlg.ShardName).c_str(),log,quiet,human); } return true; } NLMISC_CATEGORISED_COMMAND(EventManager,emWinEventStop,"stop the event that is currently running on a given event shard","") { NLMISC::CVectorSString shardNames; CEventManager::getInstance()->getShards(shardNames); DROP_IF(shardNames.empty(),"You must login before you can start or stop events",return true); AFX_MANAGE_STATE(AfxGetStaticModuleState ( )); NLMISC::CWinDisplayer *windowDisplayer = (NLMISC::CWinDisplayer*)NLNET::IService::getInstance()->WindowDisplayer; CWnd parent; parent.Attach (windowDisplayer->getHWnd()); CShardSelectWindow dlg(&parent); if (dlg.DoModal ()== IDOK) { NLMISC::ICommand::execute(NLMISC::CSString("emEventStop "+dlg.ShardName).c_str(),log,quiet,human); } return true; } #endif //----------------------------------------------------------------------------- // Dummy class that servs to force reading of last active event name at init time //----------------------------------------------------------------------------- class CEMCommandDummy: public IServiceSingleton { void init() { readVariablesFromFile(); } }; static CEMCommandDummy EMCommandDummy; //-----------------------------------------------------------------------------