Example #1
0
void C4SDefinitions::SetModules(const char *szList, const char *szRelativeToPath, const char *szRelativeToPath2)
	{
	int32_t cnt;

	// Empty list: local only
	if (!SModuleCount(szList)) 
		{ 
		LocalOnly=TRUE; 
		for (cnt=0; cnt<C4S_MaxDefinitions; cnt++) Definition[cnt][0]=0;
		return;
		}

	// Set list
	LocalOnly=FALSE;
	for (cnt=0; cnt<C4S_MaxDefinitions; cnt++) 
		{
		SGetModule(szList,cnt,Definition[cnt],_MAX_PATH);
		// Make relative path
		if (szRelativeToPath && *szRelativeToPath)
			if (SEqualNoCase(Definition[cnt],szRelativeToPath,SLen(szRelativeToPath)))
				SCopy(Definition[cnt]+SLen(szRelativeToPath),Definition[cnt]);
		if (szRelativeToPath2 && *szRelativeToPath2)
			if (SEqualNoCase(Definition[cnt],szRelativeToPath2,SLen(szRelativeToPath2)))
				SCopy(Definition[cnt]+SLen(szRelativeToPath2),Definition[cnt]);
		}

	}
void C4GameSave::WriteDescDefinitions(StdStrBuf &sBuf)
{
	// Definition specs
	if (Game.DefinitionFilenames[0])
	{
		char szDef[_MAX_PATH+1];
		// Desc
		sBuf.Append(LoadResStr("IDS_DESC_DEFSPECS"));
		// Get definition modules
		for (int cnt=0; SGetModule(Game.DefinitionFilenames,cnt,szDef); cnt++)
		{
			// Get exe relative path
			StdStrBuf sDefFilename;
			sDefFilename.Copy(Config.AtRelativePath(szDef));
			// Convert rtf backslashes
			sDefFilename.Replace("\\", "\\\\");
			// Append comma
			if (cnt>0) sBuf.Append(", ");
			// Apend to desc
			sBuf.Append(sDefFilename);
		}
		// End of line
		WriteDescLineFeed(sBuf);
	}
}
Example #3
0
void C4SDefinitions::SetModules(const char *szList, const char *szRelativeToPath, const char *szRelativeToPath2)
{
	int32_t cnt;

	// Empty list: local only
	if (!SModuleCount(szList))
	{
		LocalOnly=true;
		for (cnt=0; cnt<C4S_MaxDefinitions; cnt++) Definition[cnt][0]=0;
		return;
	}

	// Set list
	LocalOnly=false;
	for (cnt=0; cnt<C4S_MaxDefinitions; cnt++)
	{
		SGetModule(szList,cnt,Definition[cnt],_MAX_PATH);
		// Make relative path
		if (szRelativeToPath && *szRelativeToPath)
		{
			if (GetRelativePathS(Definition[cnt],szRelativeToPath) != Definition[cnt])
			{
				SCopy(GetRelativePathS(Definition[cnt],szRelativeToPath),Definition[cnt]);
				continue;
			}
		}
		if (szRelativeToPath2 && *szRelativeToPath2)
		{
			if (GetRelativePathS(Definition[cnt],szRelativeToPath2) != Definition[cnt])
			{
				SCopy(GetRelativePathS(Definition[cnt],szRelativeToPath2),Definition[cnt]);
				continue;
			}
		}
	}

}
int C4MusicSystem::SetPlayList(const char *szPlayList, bool fForceSwitch, int fadetime_ms, double max_resume_time)
{
	// Shortcut if no change
	if (playlist_valid && playlist == szPlayList) return 0;
	// info
	if (::Config.Sound.Verbose)
	{
		LogF("MusicSystem: SetPlayList(\"%s\", %s, %d, %.3lf)", szPlayList ? szPlayList : "(null)", fForceSwitch ? "true" : "false", fadetime_ms, max_resume_time);
	}
	// reset
	C4MusicFile *pFile;
	for (pFile = Songs; pFile; pFile = pFile->pNext)
	{
		pFile->NoPlay = true;
	}
	ASongCount = 0;
	if (szPlayList && *szPlayList)
	{
		// match
		char szFileName[_MAX_FNAME + 1];
		for (int cnt = 0; SGetModule(szPlayList, cnt, szFileName, _MAX_FNAME); cnt++)
			for (pFile = Songs; pFile; pFile = pFile->pNext) if (pFile->NoPlay)
				if (WildcardMatch(szFileName, GetFilename(pFile->FileName)) || pFile->HasCategory(szFileName))
				{
					ASongCount++;
					pFile->NoPlay = false;
				}
	}
	else
	{
		// default: all files except the ones beginning with an at ('@')
		// Ignore frontend and credits music
		for (pFile = Songs; pFile; pFile = pFile->pNext)
			if (*GetFilename(pFile->FileName) != '@' &&
			    !pFile->HasCategory("frontend") &&
			    !pFile->HasCategory("credits"))
			{
				ASongCount++;
				pFile->NoPlay = false;
			}
	}
	// Force switch of music if currently playing piece is not in list or idle because no music file matched
	if (fForceSwitch)
	{
		if (PlayMusicFile)
		{
			fForceSwitch = PlayMusicFile->NoPlay;
		}
		else
		{
			fForceSwitch = (!is_waiting || C4TimeMilliseconds::Now() >= wait_time_end);
		}
		if (fForceSwitch)
		{
			// Switch music. Switching to a break is also allowed, but won't be done if there is a piece to resume
			// Otherwise breaks would never occur if the playlist changes often.
			Play(NULL, false, fadetime_ms, max_resume_time, PlayMusicFile != NULL);
		}
	}
	// Remember setting (e.g. to be saved in savegames)
	playlist.Copy(szPlayList);
	playlist_valid = true; // do not re-calculate available song if playlist is reset to same value in the future
	return ASongCount;
}
Example #5
0
bool C4Group_ApplyUpdate(C4Group &hGroup) {
    // Process object update group (GRPUP_Entries.txt found)
    C4UpdatePackage Upd;
    if (hGroup.FindEntry(C4CFN_UpdateEntries))
        if (Upd.Load(&hGroup)) {
            // Do update check first (ensure packet has everything it needs in order
            // to perfom the update)
            int iRes = Upd.Check(&hGroup);
            switch (iRes) {
            // Bad version - checks against version of the applying executable
            // (major version must match, minor version must be equal or higher)
            case C4UPD_CHK_BAD_VERSION:
                fprintf(stderr,
                        "This update %s can only be applied using version "
                        "%d.%d.%d.%d or higher.\n",
                        Upd.Name, Upd.RequireVersion[0], Upd.RequireVersion[1],
                        Upd.RequireVersion[2], Upd.RequireVersion[3]);
                return false;
            // Target not found: keep going
            case C4UPD_CHK_NO_SOURCE:
                fprintf(stderr, "Target %s for update %s not found. Ignoring.\n",
                        Upd.DestPath, Upd.Name);
                return true;
            // Target mismatch: abort updating
            case C4UPD_CHK_BAD_SOURCE:
                fprintf(stderr,
                        "Target %s incorrect version for update %s. Ignoring.\n",
                        Upd.DestPath, Upd.Name);
                return true;
            // Target already updated: keep going
            case C4UPD_CHK_ALREADY_UPDATED:
                fprintf(stderr, "Target %s already up-to-date at %s.\n", Upd.DestPath,
                        Upd.Name);
                return true;
            // Ok to perform update
            case C4UPD_CHK_OK:
                printf("Updating %s to %s... ", Upd.DestPath, Upd.Name);
                // Make sure the user sees the message while the work is in progress
                fflush(stdout);
                // Execute update
                if (Upd.Execute(&hGroup)) {
                    printf("Ok\n");
                    return true;
                } else {
                    printf("Failed\n");
                    return false;
                }
            // Unknown return value from update
            default:
                fprintf(stderr, "Unknown error while updating.\n");
                return false;
            }
        }

    // Process binary update group (AutoUpdate.txt found, additional binary files
    // found)
    if (hGroup.EntryCount(C4CFN_UpdateCore))
        if (hGroup.EntryCount() - hGroup.EntryCount(C4CFN_UpdateCore) -
                hGroup.EntryCount("*.c4u") >
                0) {
            // Notice: AutoUpdate.txt is currently not processed...
            char strEntry[_MAX_FNAME + 1] = "";
            StdStrBuf strList;
            printf("Updating binaries...\n");
            hGroup.ResetSearch();
            // Look for binaries
            while (hGroup.FindNextEntry("*", strEntry))
                // Accept everything except *.c4u, AutoUpdate.txt, and c4group.exe
                // (which is assumed not to work under Windows)
                if (!WildcardMatch("*.c4u", strEntry) &&
                        !WildcardMatch(C4CFN_UpdateCore, strEntry) &&
                        !WildcardMatch("c4group.exe", strEntry)) {
                    strList += strEntry;
                    strList += ";";
                }
            // Extract binaries to current working directory
            if (!hGroup.Extract(strList.getData())) return false;
            // If extracted file is a group, explode it (this is meant for Clonk.app
            // on Mac)
            for (int i = 0; SGetModule(strList.getData(), i, strEntry); i++)
                if (C4Group_IsGroup(strEntry)) {
                    printf("Exploding: %s\n", strEntry);
                    if (!C4Group_ExplodeDirectory(strEntry)) return false;
                }
        }

    // Process any child updates (*.c4u)
    if (hGroup.FindEntry("*.c4u")) {
        // Process all children
        char strEntry[_MAX_FNAME + 1] = "";
        C4Group hChild;
        hGroup.ResetSearch();
        while (hGroup.FindNextEntry("*.c4u", strEntry))
            if (hChild.OpenAsChild(&hGroup, strEntry)) {
                bool ok = C4Group_ApplyUpdate(hChild);
                hChild.Close();
                // Failure on child update
                if (!ok) return false;
            }
    }

    // Success
    return true;
}
Example #6
0
bool C4Group_ApplyUpdate(C4Group &hGroup, unsigned long ParentProcessID)
{
	// Wait for parent process to terminate (so we can safely replace the executable)
#ifdef _WIN32
	if(ParentProcessID)
	{
		HANDLE ParentProcess = OpenProcess(SYNCHRONIZE, FALSE, ParentProcessID);
		if(ParentProcess)
		{
			// If we couldn't find a handle then either
			// a) the process terminated already, which is great.
			// b) OpenProcess() failed, which is not so great. But let's still try to do
			//    the update.
			printf("Waiting for parent process to terminate...");
			DWORD res = WaitForSingleObject(ParentProcess, 10000);
			if(res == WAIT_TIMEOUT)
				fprintf(stderr, "Parent process did not terminate after 10 seconds. Continuing...");
		}
	}
#else
	// We could use waitpid on Unix, but we don't need that functionality there anyway...
#endif

	// Process object update group (GRPUP_Entries.txt found)
	C4UpdatePackage Upd;
	if (hGroup.FindEntry(C4CFN_UpdateEntries))
		if (Upd.Load(&hGroup))
		{
			// Do update check first (ensure packet has everything it needs in order to perfom the update)
			int iRes = Upd.Check(&hGroup);
			switch (iRes)
			{
				// Bad version - checks against version of the applying executable (major version must match, minor version must be equal or higher)
			case C4UPD_CHK_BAD_VERSION:
				fprintf(stderr, "This update %s can only be applied using version %d.%d.%d.%d or higher.\n", Upd.Name, Upd.RequireVersion[0], Upd.RequireVersion[1], Upd.RequireVersion[2], Upd.RequireVersion[3]);
				return false;
				// Target not found: keep going
			case C4UPD_CHK_NO_SOURCE:
				fprintf(stderr, "Target %s for update %s not found. Ignoring.\n", Upd.DestPath, Upd.Name);
				return true;
				// Target mismatch: abort updating
			case C4UPD_CHK_BAD_SOURCE:
				fprintf(stderr, "Target %s incorrect version for update %s. Ignoring.\n", Upd.DestPath, Upd.Name);
				return true;
				// Target already updated: keep going
			case C4UPD_CHK_ALREADY_UPDATED:
				fprintf(stderr,"Target %s already up-to-date at %s.\n", Upd.DestPath, Upd.Name);
				return true;
				// Ok to perform update
			case C4UPD_CHK_OK:
				printf("Updating %s to %s... ", Upd.DestPath, Upd.Name);
				// Make sure the user sees the message while the work is in progress
				fflush(stdout);
				// Execute update
				if (Upd.Execute(&hGroup))
				{
					printf("Ok\n");
					return true;
				}
				else
				{
					printf("Failed\n");
					return false;
				}
				// Unknown return value from update
			default:
				fprintf(stderr,"Unknown error while updating.\n");
				return false;
			}
		}

	// Process binary update group (AutoUpdate.txt found, additional binary files found)
	if (hGroup.EntryCount(C4CFN_UpdateCore))
		if (hGroup.EntryCount() - hGroup.EntryCount(C4CFN_UpdateCore) - hGroup.EntryCount("*.ocu") > 0)
		{
			// Notice: AutoUpdate.txt is currently not processed...
			char strEntry[_MAX_FNAME + 1] = "";
			StdStrBuf strList;
			printf("Updating binaries...\n");
			hGroup.ResetSearch();
			// Look for binaries
			while (hGroup.FindNextEntry("*", strEntry))
				// Accept everything except *.ocu, AutoUpdate.txt, and c4group.exe (which is assumed not to work under Windows)
				if (!WildcardMatch("*.ocu", strEntry) && !WildcardMatch(C4CFN_UpdateCore, strEntry) && !WildcardMatch("c4group.exe", strEntry))
					{ strList += strEntry; strList += ";"; }
			// Extract binaries to current working directory
			if (!hGroup.Extract(strList.getData()))
				return false;
			// If extracted file is a group, explode it (this is meant for Clonk.app on Mac)
			for (int i = 0; SGetModule(strList.getData(), i, strEntry); i++)
				if (C4Group_IsGroup(strEntry))
				{
					printf("Exploding: %s\n", strEntry);
					if (!C4Group_ExplodeDirectory(strEntry))
						return false;
				}
		}

	// Process any child updates (*.ocu)
	if (hGroup.FindEntry("*.ocu"))
	{
		// Process all children
		char strEntry[_MAX_FNAME + 1] = "";
		C4Group hChild;
		hGroup.ResetSearch();
		while (hGroup.FindNextEntry("*.ocu", strEntry))
			if (hChild.OpenAsChild(&hGroup, strEntry))
			{
				bool ok = C4Group_ApplyUpdate(hChild, 0);
				hChild.Close();
				// Failure on child update
				if (!ok) return false;
			}
	}

	// Success
	return true;
}