const char *physfsDrive::GetInfo() { char **files = PHYSFS_getSearchPath(), **list = files; sprintf(info,"PHYSFS directory %s in ",basedir); while (*files != NULL) { strcat(info,*files++); strcat(info,", "); } if (PHYSFS_getWriteDir() != NULL) { strcat(info,"writing to "); strcat(info,PHYSFS_getWriteDir()); } else { strcat(info,"read-only"); } PHYSFS_freeList(list); return info; }
/*************************************************************************** Make a directory in write path and set a variable to point to it. ***************************************************************************/ static void make_dir(char *dest, const char *dirname, const char *subdir) { strcpy(dest, dirname); if (subdir != NULL) { strcat(dest, "/"); strcat(dest, subdir); } { size_t l = strlen(dest); if (dest[l - 1] != '/') { dest[l] = '/'; dest[l + 1] = '\0'; } } PHYSFS_mkdir(dest); if (!PHYSFS_mkdir(dest)) { debug(LOG_FATAL, "Unable to create directory \"%s\" in write dir \"%s\"!", dest, PHYSFS_getWriteDir()); exit(EXIT_FAILURE); } }
void wzPerfShutdown() { if (perfList.size() == 0) { return; } QString ourfile = PHYSFS_getWriteDir(); ourfile.append("gfx-performance.csv"); // write performance counter list to file QFile perf(ourfile); perf.open(QIODevice::WriteOnly); perf.write("START, EFF, TERRAIN, LOAD, PRTCL, WATER, MODELS, MISC\n"); for (int i = 0; i < perfList.size(); i++) { QString line; line += QString::number(perfList[i].counters[PERF_START_FRAME]); for (int j = 1; j < PERF_COUNT; j++) { line += ", " + QString::number(perfList[i].counters[j]); } line += "\n"; perf.write(line.toUtf8()); } // all done, clear data perfStarted = false; perfList.clear(); queryActive = PERF_COUNT; }
void vsLog_Show() { const char*writeDir = PHYSFS_getWriteDir(); if ( writeDir ) { vsSystem::Launch(writeDir); } }
std::string CResourceManager::GetSaveLocation() { if (PHYSFS_isInit()) { return PHYSFS_getWriteDir(); } return ""; }
physfsDrive::physfsDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) { char newname[CROSS_LEN+1]; /* No writedir given, use capture directory */ if(startdir[0] == ':') { strcpy(newname,capturedir.c_str()); strcat(newname,startdir); } else { strcpy(newname,startdir); } CROSS_FILENAME(newname); if (!physfs_used) { PHYSFS_init(""); PHYSFS_permitSymbolicLinks(1); } physfs_used++; char *lastdir = newname; char *dir = strchr(lastdir+(((lastdir[0]|0x20) >= 'a' && (lastdir[0]|0x20) <= 'z')?2:0),':'); while (dir) { *dir++ = 0; if((lastdir == newname) && !strchr(dir+(((dir[0]|0x20) >= 'a' && (dir[0]|0x20) <= 'z')?2:0),':')) { // If the first parameter is a directory, the next one has to be the archive file, // do not confuse it with basedir if trailing : is not there! int tmp = strlen(dir)-1; dir[tmp++] = ':'; dir[tmp++] = CROSS_FILESPLIT; dir[tmp] = '\0'; } if (*lastdir && PHYSFS_addToSearchPath(lastdir,true) == 0) { LOG_MSG("PHYSFS couldn't add '%s': %s",lastdir,PHYSFS_getLastError()); } lastdir = dir; dir = strchr(lastdir+(((lastdir[0]|0x20) >= 'a' && (lastdir[0]|0x20) <= 'z')?2:0),':'); } const char *oldwrite = PHYSFS_getWriteDir(); if (oldwrite) oldwrite = strdup(oldwrite); if (!PHYSFS_setWriteDir(newname)) { if (!oldwrite) LOG_MSG("PHYSFS can't use '%s' for writing, you might encounter problems",newname); else PHYSFS_setWriteDir(oldwrite); } if (oldwrite) free((char *)oldwrite); strcpy(basedir,lastdir); allocation.bytes_sector=_bytes_sector; allocation.sectors_cluster=_sectors_cluster; allocation.total_clusters=_total_clusters; allocation.free_clusters=_free_clusters; allocation.mediaid=_mediaid; dirCache.SetBaseDir(basedir, this); }
std::vector<std::string> getSaveDirList() { auto writeDir = PHYSFS_getWriteDir(); if (writeDir != nullptr) { return geDirList("", writeDir); } return {}; }
void vsFile::EnsureWriteDirectoryExists( const vsString &writeDirectoryName ) // static method { if ( !DirectoryExists(writeDirectoryName) ) { int mkdirResult = PHYSFS_mkdir( writeDirectoryName.c_str() ); vsAssert( mkdirResult != 0, vsFormatString("Failed to create directory '%s%s%s': %s", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(), writeDirectoryName.c_str(), PHYSFS_getLastError()) ); } }
std::string getSaveDir() { std::string saveDir = PHYSFS_getWriteDir(); if (Utils::endsWith(saveDir, "\\") == false && Utils::endsWith(saveDir, "/") == false) { saveDir += PHYSFS_getDirSeparator(); } return saveDir; }
std::string Resources::getRealWriteName(const char* filename) { const char* dir = PHYSFS_getWriteDir(); if (dir == 0) { PError << "no writedir defined" << endl; return NULL; } std::string realname = dir; realname += PHYSFS_getDirSeparator(); realname += filename; return realname; }
std::string getRealWriteName(const char* filename) { const char* dir = PHYSFS_getWriteDir(); if (dir == 0) { throw Exception("no writedir defined"); } std::string realname = dir; realname += PHYSFS_getDirSeparator(); realname += filename; return realname; }
void probeDir(const std::string& dirname) { if (PHYSFS_isDirectory(dirname.c_str()) == 0) { if (PHYSFS_exists(dirname.c_str())) { PHYSFS_delete(dirname.c_str()); } if (PHYSFS_mkdir(dirname.c_str())) { std::cout << PHYSFS_getWriteDir() << dirname << " created" << std::endl; } else { std::cout << "Warning: Creation of" << PHYSFS_getWriteDir() << dirname << " failed!" << std::endl; } } }
void print_search_path() { const char* writedir = PHYSFS_getWriteDir(); log_info << "PhysfsWritedDir: " << (writedir ? writedir : "(null)") << std::endl; log_info << "PhysfsSearchPath:" << std::endl; char** searchpath = PHYSFS_getSearchPath(); for(char** i = searchpath; *i != NULL; ++i) { log_info << " " << *i << std::endl; } PHYSFS_freeList(searchpath); }
bool deleteAll(const char* filePath, bool deleteRoot) { PHYSFS_Stat fileStat; if (PHYSFS_stat(filePath, &fileStat) == 0) { return false; } bool ret = false; if (fileStat.filetype == PHYSFS_FILETYPE_DIRECTORY) { auto paths = PHYSFS_enumerateFiles(filePath); if (paths != nullptr) { auto writeDir = PHYSFS_getWriteDir(); if (writeDir != nullptr) { for (char** path = paths; *path != nullptr; path++) { auto fullPath = std::string(filePath) + '/' + *path; if (PHYSFS_stat(fullPath.c_str(), &fileStat) == 0) { continue; } if (fileStat.filetype == PHYSFS_FILETYPE_DIRECTORY) { deleteAll(fullPath.c_str(), true); } else { auto realDir = PHYSFS_getRealDir(fullPath.c_str()); if (realDir != nullptr) { if (std::strcmp(writeDir, realDir) == 0) { ret = PHYSFS_delete(fullPath.c_str()) != 0; } } } } } PHYSFS_freeList(paths); } if (deleteRoot == true) { ret = PHYSFS_delete(filePath) != 0; } } else { ret = PHYSFS_delete(filePath) != 0; } return ret; }
// returns -1 if error // Gets bytes free in current write dir PHYSFS_sint64 PHYSFSX_getFreeDiskSpace() { #if defined(__linux__) || (defined(__MACH__) && defined(__APPLE__)) struct statfs sfs; if (!statfs(PHYSFS_getWriteDir(), &sfs)) return (PHYSFS_sint64)(sfs.f_bavail * sfs.f_bsize); return -1; #else return 0x7FFFFFFF; #endif }
bool deleteFile(const char* filePath) noexcept { auto writeDir = PHYSFS_getWriteDir(); auto realDir = PHYSFS_getRealDir(filePath); if (writeDir != nullptr && realDir != nullptr) { if (strcmp(writeDir, realDir) == 0) { return PHYSFS_delete(filePath) != 0; } } return false; }
std::map<std::string, EcKey::Key> const &getKnownPlayers() { if (knownPlayersIni == nullptr) { knownPlayersIni = new QSettings(PHYSFS_getWriteDir() + QString("/") + "knownPlayers.ini", QSettings::IniFormat); QStringList names = knownPlayersIni->allKeys(); for (int i = 0; i < names.size(); ++i) { knownPlayers[names[i].toUtf8().constData()] = base64Decode(knownPlayersIni->value(names[i]).toString().toStdString()); } } return knownPlayers; }
void FileSystem::probeDir(const std::string& dirname) { if ( !isDirectory(dirname) ) { if (exists(dirname)) { /// \todo simple delete such files without a warning??? deleteFile(dirname); } if (mkdir(dirname)) { std::cout << PHYSFS_getWriteDir() << dirname << " created" << std::endl; } else { std::cout << "Warning: Creation of" << PHYSFS_getWriteDir() << dirname << " failed!" << std::endl; } } }
/**\brief Save an XML file for this player * \details The filename is by default the player's name. */ void Player::Save( string scenario ) { xmlDocPtr xmlPtr; LogMsg( INFO, "Creation of %s", GetFileName().c_str() ); // Create new XML Document xmlPtr = xmlNewDoc( BAD_CAST "1.0" ); xmlNodePtr root_node = ToXMLNode("player"); xmlDocSetRootElement(xmlPtr, root_node); xmlSaveFormatFileEnc( (std::string(PHYSFS_getWriteDir()) + std::string(PHYSFS_getDirSeparator()) + GetFileName()).c_str(), xmlPtr, "ISO-8859-1", 1); // Update and Save this player's info in the master players list. PlayerList::Instance()->GetPlayerInfo( GetName() )->Update( this, scenario ); PlayerList::Instance()->Save(); }
bool physfsFile::prepareWrite() { const char *wdir = PHYSFS_getWriteDir(); if (wdir == NULL) { LOG_MSG("PHYSFS could not fulfill write request: no write directory set."); return false; } //LOG_MSG("Goto write (%s at %i)",pname,PHYSFS_tell(fhandle)); const char *fdir = PHYSFS_getRealDir(pname); PHYSFS_uint64 pos = PHYSFS_tell(fhandle); char *slash = strrchr(pname,'/'); if (slash && slash != pname) { *slash = 0; PHYSFS_mkdir(pname); *slash = '/'; } if (strcmp(fdir,wdir)) { /* we need COW */ //LOG_MSG("COW",pname,PHYSFS_tell(fhandle)); PHYSFS_file *whandle = PHYSFS_openWrite(pname); if (whandle == NULL) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); return false; } char buffer[65536]; PHYSFS_sint64 size; PHYSFS_seek(fhandle, 0); while ((size = PHYSFS_read(fhandle,buffer,1,65536)) > 0) { if (PHYSFS_write(whandle,buffer,1,(PHYSFS_uint32)size) != size) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); PHYSFS_close(whandle); return false; } } PHYSFS_seek(whandle, pos); PHYSFS_close(fhandle); fhandle = whandle; } else { // megayuck - physfs on posix platforms uses O_APPEND. We illegally access the fd directly and clear that flag. //LOG_MSG("noCOW",pname,PHYSFS_tell(fhandle)); PHYSFS_close(fhandle); fhandle = PHYSFS_openAppend(pname); #ifndef WIN32 fcntl(**(int**)fhandle->opaque,F_SETFL,0); #endif PHYSFS_seek(fhandle, pos); } return true; }
bool File::open(Mode mode) { if (mode == CLOSED) return true; // File must exist if read mode. if ((mode == READ) && !PHYSFS_exists(filename.c_str())) throw love::Exception("Could not open file %s. Does not exist.", filename.c_str()); // Check whether the write directory is set. if ((mode == APPEND || mode == WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory()) throw love::Exception("Could not set write directory."); // File already open? if (file != 0) return false; this->mode = mode; switch (mode) { case READ: file = PHYSFS_openRead(filename.c_str()); break; case APPEND: file = PHYSFS_openAppend(filename.c_str()); break; case WRITE: file = PHYSFS_openWrite(filename.c_str()); break; default: break; } if (file != 0 && !setBuffer(bufferMode, bufferSize)) { // Revert to buffer defaults if we don't successfully set the buffer. bufferMode = BUFFER_NONE; bufferSize = 0; } return (file != 0); }
int PHYSFSX_getRealPath(const char *stdPath, char *realPath) { const char *realDir = PHYSFS_getRealDir(stdPath); const char *sep = PHYSFS_getDirSeparator(); char *p; if (!realDir) { realDir = PHYSFS_getWriteDir(); if (!realDir) return 0; } strncpy(realPath, realDir, PATH_MAX - 1); if (strlen(realPath) >= strlen(sep)) { p = realPath + strlen(realPath) - strlen(sep); if (strcmp(p, sep)) // no sep at end of realPath strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath)); } if (strlen(stdPath) >= 1) if (*stdPath == '/') stdPath++; while (*stdPath) { if (*stdPath == '/') strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath)); else { if (strlen(realPath) < PATH_MAX - 2) { p = realPath + strlen(realPath); p[0] = *stdPath; p[1] = '\0'; } } stdPath++; } return 1; }
bool File::open() { // Check whether the write directory is set. if((mode == love::FILE_APPEND || mode == love::FILE_WRITE) && (PHYSFS_getWriteDir() == 0)) if(!setupWriteDirectory()) return false; switch(mode) { case love::FILE_READ: file = PHYSFS_openRead(filename.c_str()); break; case love::FILE_APPEND: file = PHYSFS_openAppend(filename.c_str()); break; case love::FILE_WRITE: file = PHYSFS_openWrite(filename.c_str()); break; } return (file != 0); }
bool File::open(Mode mode) { if(mode == CLOSED) return true; // File must exist if read mode. if((mode == READ) && !PHYSFS_exists(filename.c_str())) throw love::Exception("Could not open file %s. Does not exist.", filename.c_str()); // Check whether the write directory is set. if((mode == APPEND || mode == WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory()) throw love::Exception("Could not set write directory."); // File already open? if(file != 0) return false; this->mode = mode; switch(mode) { case READ: file = PHYSFS_openRead(filename.c_str()); break; case APPEND: file = PHYSFS_openAppend(filename.c_str()); break; case WRITE: file = PHYSFS_openWrite(filename.c_str()); break; default: break; } return (file != 0); }
/*! * \brief Rebuilds the PHYSFS searchPath with mode specific subdirs * * Priority: * maps > mods > base > base.wz */ bool rebuildSearchPath( searchPathMode mode, bool force ) { static searchPathMode current_mode = mod_clean; static std::string current_current_map; wzSearchPath * curSearchPath = searchPathRegistry; char tmpstr[PATH_MAX] = "\0"; if (mode != current_mode || (current_map != NULL? current_map : "") != current_current_map || force || (use_override_mods && strcmp(override_mod_list, getModList()))) { if (mode != mod_clean) { rebuildSearchPath( mod_clean, false ); } current_mode = mode; current_current_map = current_map != NULL? current_map : ""; // Start at the lowest priority while( curSearchPath->lowerPriority ) curSearchPath = curSearchPath->lowerPriority; switch ( mode ) { case mod_clean: debug(LOG_WZ, "Cleaning up"); clearLoadedMods(); while( curSearchPath ) { #ifdef DEBUG debug(LOG_WZ, "Removing [%s] from search path", curSearchPath->path); #endif // DEBUG // Remove maps and mods removeSubdirs( curSearchPath->path, "maps", NULL ); removeSubdirs( curSearchPath->path, "mods/music", NULL ); removeSubdirs( curSearchPath->path, "mods/global", NULL ); removeSubdirs( curSearchPath->path, "mods/campaign", NULL ); removeSubdirs( curSearchPath->path, "mods/multiplay", NULL ); removeSubdirs( curSearchPath->path, "mods/autoload", NULL ); // Remove multiplay patches sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "mp"); PHYSFS_removeFromSearchPath( tmpstr ); sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "mp.wz"); PHYSFS_removeFromSearchPath( tmpstr ); // Remove plain dir PHYSFS_removeFromSearchPath( curSearchPath->path ); // Remove base files sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base"); PHYSFS_removeFromSearchPath( tmpstr ); sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base.wz"); PHYSFS_removeFromSearchPath( tmpstr ); // remove video search path as well sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "sequences.wz"); PHYSFS_removeFromSearchPath( tmpstr ); curSearchPath = curSearchPath->higherPriority; } break; case mod_campaign: debug(LOG_WZ, "*** Switching to campaign mods ***"); clearLoadedMods(); while (curSearchPath) { // make sure videos override included files sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "sequences.wz"); PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND); curSearchPath = curSearchPath->higherPriority; } curSearchPath = searchPathRegistry; while (curSearchPath->lowerPriority) curSearchPath = curSearchPath->lowerPriority; while( curSearchPath ) { #ifdef DEBUG debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path); #endif // DEBUG // Add global and campaign mods PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND ); addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false ); addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true ); addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true ); addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true ); addSubdirs( curSearchPath->path, "mods/campaign", PHYSFS_APPEND, use_override_mods?override_mods:campaign_mods, true ); if (!PHYSFS_removeFromSearchPath( curSearchPath->path )) { debug(LOG_WZ, "* Failed to remove path %s again", curSearchPath->path); } // Add plain dir PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND ); // Add base files sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base.wz"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); curSearchPath = curSearchPath->higherPriority; } break; case mod_multiplay: debug(LOG_WZ, "*** Switching to multiplay mods ***"); clearLoadedMods(); while (curSearchPath) { // make sure videos override included files sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "sequences.wz"); PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND); curSearchPath = curSearchPath->higherPriority; } // Add the selected map first, for mapmod support if (current_map != NULL) { std::string realPathAndDir = std::string(PHYSFS_getRealDir(current_map)) + current_map; PHYSFS_addToSearchPath(realPathAndDir.c_str(), PHYSFS_APPEND); } curSearchPath = searchPathRegistry; while (curSearchPath->lowerPriority) curSearchPath = curSearchPath->lowerPriority; while( curSearchPath ) { #ifdef DEBUG debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path); #endif // DEBUG // Add global and multiplay mods PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND ); addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false ); addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true ); addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true ); addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true ); addSubdirs( curSearchPath->path, "mods/multiplay", PHYSFS_APPEND, use_override_mods?override_mods:multiplay_mods, true ); PHYSFS_removeFromSearchPath( curSearchPath->path ); // Add multiplay patches sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "mp"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "mp.wz"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); // Add plain dir PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND ); // Add base files sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); sstrcpy(tmpstr, curSearchPath->path); sstrcat(tmpstr, "base.wz"); PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND ); curSearchPath = curSearchPath->higherPriority; } break; default: debug(LOG_ERROR, "Can't switch to unknown mods %i", mode); return false; } if (use_override_mods && mode != mod_clean) { if (strcmp(getModList(),override_mod_list)) { debug(LOG_POPUP, _("The required mod could not be loaded: %s\n\nWarzone will try to load the game without it."), override_mod_list); } clearOverrideMods(); current_mode = mod_override; } // User's home dir must be first so we allways see what we write PHYSFS_removeFromSearchPath(PHYSFS_getWriteDir()); PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND ); #ifdef DEBUG printSearchPath(); #endif // DEBUG } else if (use_override_mods) { // override mods are already the same as current mods, so no need to do anything clearOverrideMods(); } return true; }
// Saves and loads the relevant part of the config files for MP games // Ensures that others' games don't change our own configuration settings bool reloadMPConfig(void) { QSettings ini(PHYSFS_getWriteDir() + QString("/") + fileName, QSettings::IniFormat); if (ini.status() != QSettings::NoError) { debug(LOG_ERROR, "Could not open configuration file \"%s\"", fileName); return false; } debug(LOG_WZ, "Reloading prefs prefs to registry"); // If we're in-game, we already have our own configuration set, so no need to reload it. if (NetPlay.isHost && !ingame.localJoiningInProgress) { if (bMultiPlayer && !NetPlay.bComms) { // one-player skirmish mode sets game name to "One Player Skirmish", so // reset the name if (ini.contains("gameName")) { sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData()); } } return true; } // If we're host and not in-game, we can safely save our settings and return. if (NetPlay.isHost && ingame.localJoiningInProgress) { if (bMultiPlayer && NetPlay.bComms) { ini.setValue("gameName", game.name); // last hosted game } else { // One-player skirmish mode sets game name to "One Player Skirmish", so // reset the name if (ini.contains("gameName")) { sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData()); } } // Set a default map to prevent hosting games without a map. sstrcpy(game.map, "Sk-Rush"); game.hash.setZero(); game.maxPlayers = 4; ini.setValue("power", game.power); // power ini.setValue("base", game.base); // size of base ini.setValue("alliance", game.alliance); // allow alliances return true; } // We're not host, so let's get rid of the host's game settings and restore our own. // game name if (ini.contains("gameName")) { sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData()); } // Set a default map to prevent hosting games without a map. sstrcpy(game.map, "Sk-Rush"); game.hash.setZero(); game.maxPlayers = 4; game.power = ini.value("power", LEV_MED).toInt(); game.base = ini.value("base", CAMP_BASE).toInt(); game.alliance = ini.value("alliance", NO_ALLIANCES).toInt(); return true; }
/*! * \brief Adds default data dirs * * Priority: * Lower loads first. Current: * -datadir > User's home dir > source tree data > AutoPackage > BaseDir > DEFAULT_DATADIR * * Only -datadir and home dir are allways examined. Others only if data still not found. * * We need ParseCommandLine, before we can add any mods... * * \sa rebuildSearchPath */ static void scanDataDirs( void ) { char tmpstr[PATH_MAX], prefix[PATH_MAX]; char* separator; #if defined(WZ_OS_MAC) // version-independent location for video files registerSearchPath("/Library/Application Support/Warzone 2100/", 1); #endif // Find out which PREFIX we are in... sstrcpy(prefix, PHYSFS_getBaseDir()); separator = strrchr(prefix, *PHYSFS_getDirSeparator()); if (separator) { *separator = '\0'; // Trim ending '/', which getBaseDir always provides separator = strrchr(prefix, *PHYSFS_getDirSeparator()); if (separator) { *separator = '\0'; // Skip the last dir from base dir } } // Commandline supplied datadir if( strlen( datadir ) != 0 ) registerSearchPath( datadir, 1 ); // User's home dir registerSearchPath( PHYSFS_getWriteDir(), 2 ); rebuildSearchPath( mod_multiplay, true ); if( !PHYSFS_exists("gamedesc.lev") ) { // Data in source tree sstrcpy(tmpstr, prefix); sstrcat(tmpstr, "/data/"); registerSearchPath( tmpstr, 3 ); rebuildSearchPath( mod_multiplay, true ); if( !PHYSFS_exists("gamedesc.lev") ) { // Relocation for AutoPackage sstrcpy(tmpstr, prefix); sstrcat(tmpstr, "/share/warzone2100/"); registerSearchPath( tmpstr, 4 ); rebuildSearchPath( mod_multiplay, true ); if( !PHYSFS_exists("gamedesc.lev") ) { // Program dir registerSearchPath( PHYSFS_getBaseDir(), 5 ); rebuildSearchPath( mod_multiplay, true ); if( !PHYSFS_exists("gamedesc.lev") ) { // Guessed fallback default datadir on Unix registerSearchPath( WZ_DATADIR, 6 ); rebuildSearchPath( mod_multiplay, true ); } } } } #ifdef WZ_OS_MAC if( !PHYSFS_exists("gamedesc.lev") ) { CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); char resourcePath[PATH_MAX]; if( CFURLGetFileSystemRepresentation( resourceURL, true, (UInt8 *) resourcePath, PATH_MAX) ) { chdir( resourcePath ); registerSearchPath( "data", 7 ); rebuildSearchPath( mod_multiplay, true ); } else { debug( LOG_ERROR, "Could not change to resources directory." ); } if( resourceURL != NULL ) { CFRelease( resourceURL ); } } #endif /** Debugging and sanity checks **/ printSearchPath(); if( PHYSFS_exists("gamedesc.lev") ) { debug( LOG_WZ, "gamedesc.lev found at %s", PHYSFS_getRealDir( "gamedesc.lev" ) ); } else { debug( LOG_FATAL, "Could not find game data. Aborting." ); exit(1); } }
static void getPlatformUserDir(char * const tmpstr, size_t const size) { #if defined(WZ_OS_WIN) // When WZ_PORTABLE is passed, that means we want the config directory at the same location as the program file DWORD dwRet; wchar_t tmpWStr[MAX_PATH]; #ifndef WZ_PORTABLE if ( SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmpWStr ) ) ) { #else if (dwRet = GetCurrentDirectoryW(MAX_PATH, tmpWStr)) { if(dwRet > MAX_PATH) { debug(LOG_FATAL, "Buffer exceeds maximum path to create directory. Exiting."); exit(1); } #endif if (WideCharToMultiByte(CP_UTF8, 0, tmpWStr, -1, tmpstr, size, NULL, NULL) == 0) { debug(LOG_FATAL, "Config directory encoding conversion error."); exit(1); } strlcat(tmpstr, PHYSFS_getDirSeparator(), size); } else #elif defined(WZ_OS_MAC) FSRef fsref; OSErr error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &fsref); if (!error) error = FSRefMakePath(&fsref, (UInt8 *) tmpstr, size); if (!error) strlcat(tmpstr, PHYSFS_getDirSeparator(), size); else #endif if (PHYSFS_getUserDir()) { strlcpy(tmpstr, PHYSFS_getUserDir(), size); // Use PhysFS supplied UserDir (As fallback on Windows / Mac, default on Linux) } // If PhysicsFS fails (might happen if environment variable HOME is unset or wrong) then use the current working directory else if (getCurrentDir(tmpstr, size)) { strlcat(tmpstr, PHYSFS_getDirSeparator(), size); } else { debug(LOG_FATAL, "Can't get UserDir?"); abort(); } } static void initialize_ConfigDir(void) { char tmpstr[PATH_MAX] = { '\0' }; if (strlen(configdir) == 0) { getPlatformUserDir(tmpstr, sizeof(tmpstr)); if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected. { debug(LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError()); exit(1); } if (!PHYSFS_mkdir(WZ_WRITEDIR)) // s.a. { debug(LOG_FATAL, "Error creating directory \"%s\": %s", WZ_WRITEDIR, PHYSFS_getLastError()); exit(1); } // Append the Warzone subdir sstrcat(tmpstr, WZ_WRITEDIR); sstrcat(tmpstr, PHYSFS_getDirSeparator()); if (!PHYSFS_setWriteDir(tmpstr)) { debug( LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError() ); exit(1); } } else { sstrcpy(tmpstr, configdir); // Make sure that we have a directory separator at the end of the string if (tmpstr[strlen(tmpstr) - 1] != PHYSFS_getDirSeparator()[0]) sstrcat(tmpstr, PHYSFS_getDirSeparator()); debug(LOG_WZ, "Using custom configuration directory: %s", tmpstr); if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected. { debug(LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError()); exit(1); } // NOTE: This is currently only used for mingw builds for now. #if defined (WZ_CC_MINGW) if (!OverrideRPTDirectory(tmpstr)) { // since it failed, we just use our default path, and not the user supplied one. debug(LOG_ERROR, "Error setting exception hanlder to use directory %s", tmpstr); } #endif } // User's home dir first so we allways see what we write PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND ); PHYSFS_permitSymbolicLinks(1); debug(LOG_WZ, "Write dir: %s", PHYSFS_getWriteDir()); debug(LOG_WZ, "Base dir: %s", PHYSFS_getBaseDir()); }
int realmain(int argc, char *argv[]) { // The libcrypto startup stuff... May or may not actually be needed for anything at all. ERR_load_crypto_strings(); // This is needed for descriptive error messages. OpenSSL_add_all_algorithms(); // Don't actually use the EVP functions, so probably not needed. OPENSSL_config(nullptr); // What does this actually do? #ifdef WZ_OS_WIN RAND_screen(); // Uses a screenshot as a random seed, on systems lacking /dev/random. #endif wzMain(argc, argv); int utfargc = argc; const char** utfargv = (const char**)argv; #ifdef WZ_OS_MAC cocoaInit(); #endif debug_init(); debug_register_callback( debug_callback_stderr, NULL, NULL, NULL ); #if defined(WZ_OS_WIN) && defined(DEBUG_INSANE) debug_register_callback( debug_callback_win32debug, NULL, NULL, NULL ); #endif // WZ_OS_WIN && DEBUG_INSANE // ***** // NOTE: Try *NOT* to use debug() output routines without some other method of informing the user. All this output is sent to /dev/nul at this point on some platforms! // ***** if (!getUTF8CmdLine(&utfargc, &utfargv)) { return EXIT_FAILURE; } QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // make Qt treat all C strings in Warzone as UTF-8 setupExceptionHandler(utfargc, utfargv, version_getFormattedVersionString()); /*** Initialize PhysicsFS ***/ initialize_PhysicsFS(utfargv[0]); /*** Initialize translations ***/ initI18n(); // find early boot info if (!ParseCommandLineEarly(utfargc, utfargv)) { return EXIT_FAILURE; } /* Initialize the write/config directory for PhysicsFS. * This needs to be done __after__ the early commandline parsing, * because the user might tell us to use an alternative configuration * directory. */ initialize_ConfigDir(); /*** Initialize directory structure ***/ make_dir(ScreenDumpPath, "screenshots", NULL); make_dir(SaveGamePath, "savegames", NULL); PHYSFS_mkdir("savegames/campaign"); PHYSFS_mkdir("savegames/skirmish"); make_dir(MultiCustomMapsPath, "maps", NULL); // MUST have this to prevent crashes when getting map PHYSFS_mkdir("music"); PHYSFS_mkdir("logs"); // a place to hold our netplay, mingw crash reports & WZ logs PHYSFS_mkdir("userdata"); // a place to store per-mod data user generated data memset(rulesettag, 0, sizeof(rulesettag)); // tag to add to userdata to find user generated stuff make_dir(MultiPlayersPath, "multiplay", NULL); make_dir(MultiPlayersPath, "multiplay", "players"); if (!customDebugfile) { // there was no custom debug file specified (--debug-file=blah) // so we use our write directory to store our logs. time_t aclock; struct tm *newtime; char buf[PATH_MAX]; time( &aclock ); // Get time in seconds newtime = localtime( &aclock ); // Convert time to struct // Note: We are using fopen(), and not physfs routines to open the file // log name is logs/(or \)WZlog-MMDD_HHMMSS.txt snprintf(buf, sizeof(buf), "%slogs%sWZlog-%02d%02d_%02d%02d%02d.txt", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec ); debug_register_callback( debug_callback_file, debug_callback_file_init, debug_callback_file_exit, buf ); // FIXME: Change this to LOG_WZ on next release debug(LOG_INFO, "Using %s debug file", buf); } // NOTE: it is now safe to use debug() calls to make sure output gets captured. check_Physfs(); debug(LOG_WZ, "Warzone 2100 - %s", version_getFormattedVersionString()); debug(LOG_WZ, "Using language: %s", getLanguage()); debug(LOG_WZ, "Backend: %s", BACKEND); debug(LOG_MEMORY, "sizeof: SIMPLE_OBJECT=%ld, BASE_OBJECT=%ld, DROID=%ld, STRUCTURE=%ld, FEATURE=%ld, PROJECTILE=%ld", (long)sizeof(SIMPLE_OBJECT), (long)sizeof(BASE_OBJECT), (long)sizeof(DROID), (long)sizeof(STRUCTURE), (long)sizeof(FEATURE), (long)sizeof(PROJECTILE)); /* Put in the writedir root */ sstrcpy(KeyMapPath, "keymap.map"); // initialise all the command line states war_SetDefaultStates(); debug(LOG_MAIN, "initializing"); PhysicsEngineHandler engine; // register abstract physfs filesystem loadConfig(); // parse the command line if (!ParseCommandLine(utfargc, utfargv)) { return EXIT_FAILURE; } // Save new (commandline) settings saveConfig(); // Find out where to find the data scanDataDirs(); // Now we check the mods to see if they exist or not (specified on the command line) // They are all capped at 100 mods max(see clparse.c) // FIX ME: I know this is a bit hackish, but better than nothing for now? { char *modname; char modtocheck[256]; int i = 0; int result = 0; // check global mods for(i=0; i < 100; i++) { modname = global_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/global/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The (global) mod (%s) you have specified doesn't exist!", modname); } else { info("(global) mod (%s) is enabled", modname); } } // check campaign mods for(i=0; i < 100; i++) { modname = campaign_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/campaign/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_ca (%s) you have specified doesn't exist!", modname); } else { info("mod_ca (%s) is enabled", modname); } } // check multiplay mods for(i=0; i < 100; i++) { modname = multiplay_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/multiplay/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_mp (%s) you have specified doesn't exist!", modname); } else { info("mod_mp (%s) is enabled", modname); } } } if (!wzMain2(war_getFSAA(), war_getFullscreen(), war_GetVsync())) { return EXIT_FAILURE; } int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); char buf[256]; ssprintf(buf, "Video Mode %d x %d (%s)", w, h, war_getFullscreen() ? "fullscreen" : "window"); addDumpInfo(buf); debug(LOG_MAIN, "Final initialization"); if (!frameInitialise()) { return EXIT_FAILURE; } if (!screenInitialise()) { return EXIT_FAILURE; } if (!pie_LoadShaders()) { return EXIT_FAILURE; } war_SetWidth(pie_GetVideoBufferWidth()); war_SetHeight(pie_GetVideoBufferHeight()); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); pal_Init(); pie_LoadBackDrop(SCREEN_RANDOMBDROP); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); if (!systemInitialise()) { return EXIT_FAILURE; } //set all the pause states to false setAllPauseStates(false); // Copy this info to be used by the crash handler for the dump file ssprintf(buf,"Using Backend: %s", BACKEND); addDumpInfo(buf); ssprintf(buf,"Using language: %s", getLanguageName()); addDumpInfo(buf); // Do the game mode specific initialisation. switch(GetGameMode()) { case GS_TITLE_SCREEN: startTitleLoop(); break; case GS_SAVEGAMELOAD: initSaveGameLoad(); break; case GS_NORMAL: startGameLoop(); break; default: debug(LOG_ERROR, "Weirdy game status, I'm afraid!!"); break; } #if defined(WZ_CC_MSVC) && defined(DEBUG) debug_MEMSTATS(); #endif debug(LOG_MAIN, "Entering main loop"); wzMain3(); saveConfig(); systemShutdown(); #ifdef WZ_OS_WIN // clean up the memory allocated for the command line conversion for (int i=0; i<argc; i++) { const char*** const utfargvF = &utfargv; free((void *)(*utfargvF)[i]); } free(utfargv); #endif wzShutdown(); debug(LOG_MAIN, "Completed shutting down Warzone 2100"); return EXIT_SUCCESS; }
// //////////////////////////////////////////////////////////////////////////// bool loadConfig() { QSettings ini(PHYSFS_getWriteDir() + QString("/") + fileName, QSettings::IniFormat); if (ini.status() != QSettings::NoError) { debug(LOG_ERROR, "Could not open configuration file \"%s\"", fileName); return false; } debug(LOG_WZ, "Reading configuration from %s", ini.fileName().toUtf8().constData()); if (ini.contains("voicevol")) sound_SetUIVolume(ini.value("voicevol").toDouble() / 100.0); if (ini.contains("fxvol")) sound_SetEffectsVolume(ini.value("fxvol").toDouble() / 100.0); if (ini.contains("cdvol")) sound_SetMusicVolume(ini.value("cdvol").toDouble() / 100.0); if (ini.contains("music_enabled")) war_SetMusicEnabled(ini.value("music_enabled").toBool()); if (ini.contains("language")) setLanguage(ini.value("language").toString().toUtf8().constData()); if (ini.contains("nomousewarp")) setMouseWarp(ini.value("nomousewarp").toBool()); if (ini.contains("notexturecompression")) wz_texture_compression = GL_RGBA; showFPS = ini.value("showFPS", false).toBool(); scroll_speed_accel = ini.value("scroll", DEFAULTSCROLL).toInt(); setShakeStatus(ini.value("shake", false).toBool()); setDrawShadows(ini.value("shadows", true).toBool()); war_setSoundEnabled(ini.value("sound", true).toBool()); setInvertMouseStatus(ini.value("mouseflip", true).toBool()); setRightClickOrders(ini.value("RightClickOrders", false).toBool()); setMiddleClickRotate(ini.value("MiddleClickRotate", false).toBool()); rotateRadar = ini.value("rotateRadar", true).toBool(); war_SetPauseOnFocusLoss(ini.value("PauseOnFocusLoss", false).toBool()); NETsetMasterserverName(ini.value("masterserver_name", "lobby.wz2100.net").toString().toUtf8().constData()); iV_font(ini.value("fontname", "DejaVu Sans").toString().toUtf8().constData(), ini.value("fontface", "Book").toString().toUtf8().constData(), ini.value("fontfacebold", "Bold").toString().toUtf8().constData()); NETsetMasterserverPort(ini.value("masterserver_port", MASTERSERVERPORT).toInt()); NETsetGameserverPort(ini.value("gameserver_port", GAMESERVERPORT).toInt()); war_SetFMVmode((FMV_MODE)ini.value("FMVmode", FMV_FULLSCREEN).toInt()); war_setScanlineMode((SCANLINE_MODE)ini.value("scanlines", SCANLINES_OFF).toInt()); seq_SetSubtitles(ini.value("subtitles", true).toBool()); setDifficultyLevel((DIFFICULTY_LEVEL)ini.value("difficulty", DL_NORMAL).toInt()); war_SetSPcolor(ini.value("colour", 0).toInt()); // default is green (0) war_setMPcolour(ini.value("colourMP", -1).toInt()); // default is random (-1) sstrcpy(game.name, ini.value("gameName", _("My Game")).toString().toUtf8().constData()); sstrcpy(sPlayer, ini.value("playerName", _("Player")).toString().toUtf8().constData()); // Set a default map to prevent hosting games without a map. sstrcpy(game.map, "Sk-Rush"); game.hash.setZero(); game.maxPlayers = 4; game.power = ini.value("power", LEV_MED).toInt(); game.base = ini.value("base", CAMP_BASE).toInt(); game.alliance = ini.value("alliance", NO_ALLIANCES).toInt(); game.scavengers = ini.value("scavengers", false).toBool(); memset(&ingame.phrases, 0, sizeof(ingame.phrases)); for (int i = 1; i < 5; i++) { QString key("phrase" + QString::number(i)); if (ini.contains(key)) sstrcpy(ingame.phrases[i], ini.value(key).toString().toUtf8().constData()); } bEnemyAllyRadarColor = ini.value("radarObjectMode").toBool(); radarDrawMode = (RADAR_DRAW_MODE)ini.value("radarTerrainMode", RADAR_MODE_DEFAULT).toInt(); radarDrawMode = (RADAR_DRAW_MODE)MIN(NUM_RADAR_MODES - 1, radarDrawMode); // restrict to allowed values if (ini.contains("textureSize")) setTextureSize(ini.value("textureSize").toInt()); NetPlay.isUPNP = ini.value("UPnP", true).toBool(); if (ini.contains("FSAA")) war_setFSAA(ini.value("FSAA").toInt()); // Leave this to false, some system will fail and they can't see the system popup dialog! war_setFullscreen(ini.value("fullscreen", false).toBool()); war_SetTrapCursor(ini.value("trapCursor", false).toBool()); // this should be enabled on all systems by default war_SetVsync(ini.value("vsync", true).toBool()); // 640x480 is minimum that we will support int width = ini.value("width", 640).toInt(); int height = ini.value("height", 480).toInt(); if (width < 640 || height < 480) // sanity check { width = 640; height = 480; } pie_SetVideoBufferWidth(width); pie_SetVideoBufferHeight(height); war_SetWidth(width); war_SetHeight(height); if (ini.contains("bpp")) pie_SetVideoBufferDepth(ini.value("bpp").toInt()); return true; }