Example #1
0
void C4Network2IRCChannel::OnUsers(const char *szUsers, const char *szPrefixes)
	{
	// Find actual prefixes
	szPrefixes = SSearch(szPrefixes, ")");
	// Reconstructs the list
	if(!fReceivingUsers)
		ClearUsers();
	while(szUsers && *szUsers)
		{
		// Get user name
		StdStrBuf PrefixedName = ircExtractPar(&szUsers);
		// Remove prefix(es)
		const char *szName = PrefixedName.getData();
		if(szPrefixes)
			while(strchr(szPrefixes, *szName))
				szName++;
		// Copy prefix
		StdStrBuf Prefix;
		Prefix.Copy(PrefixedName.getData(), szName - PrefixedName.getData());
		// Add user
		AddUser(szName)->SetPrefix(Prefix.getData());
		}
	// Set flag the user list won't get cleared again until OnUsersEnd is called
	fReceivingUsers = true;
	}
bool C4Network2Res::SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName, bool fSilent)
{
	CStdLock FileLock(&FileCSec);
	// default resource name: relative path
	if (!szResName) szResName = Config.AtRelativePath(strFilePath);
	SCopy(strFilePath, szFile, sizeof(szFile)-1);
	// group?
	C4Group Grp;
	if (Reloc.Open(Grp, strFilePath))
		return SetByGroup(&Grp, fTemp, eType, iResID, szResName, fSilent);
	// so it needs to be a file
	StdStrBuf szFullFile;
	if (!Reloc.LocateItem(szFile, szFullFile))
		{ if (!fSilent) LogF("SetByFile: file %s not found!", strFilePath); return false; }
	// calc checksum
	uint32_t iCRC32;
	if (!GetFileCRC(szFullFile.getData(), &iCRC32)) return false;
#ifdef C4NET2RES_DEBUG_LOG
	// log
	LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, szResName, szFile, fTemp ? "temp" : "static");
#endif
	// set core
	Core.Set(eType, iResID, Config.AtRelativePath(szFullFile.getData()), iCRC32);
	// set own data
	fDirty = true;
	fTempFile = fTemp;
	fStandaloneFailed = false;
	fRemoved = false;
	iLastReqTime = time(NULL);
	fLoading = false;
	// ok
	return true;
}
Example #3
0
bool OpenLog()
{
	// open
	sLogFileName = C4CFN_Log; int iLog = 2;
#ifdef _WIN32
	while (!(C4LogFile = _fsopen(Config.AtUserDataPath(sLogFileName.getData()), "wt", _SH_DENYWR)))
#elif defined(HAVE_SYS_FILE_H)
	int fd = 0;
	while (!(fd = open(Config.AtUserDataPath(sLogFileName.getData()), O_WRONLY | O_CREAT, 0644)) || flock(fd, LOCK_EX|LOCK_NB))
#else
	while (!(C4LogFile = fopen(Config.AtUserDataPath(sLogFileName.getData()), "wb")))
#endif
	{
		// Already locked by another instance?
#if !defined(_WIN32) && defined(HAVE_SYS_FILE_H)
		if (fd) close(fd);
#else
		if (C4LogFile) fclose(C4LogFile);
#endif
		// If the file does not yet exist, the directory is r/o
		// don't go on then, or we have an infinite loop
		if (access(Config.AtUserDataPath(sLogFileName.getData()), 0))
			return false;
		// try different name
		sLogFileName.Format(C4CFN_LogEx, iLog++);
	}
#if !defined(_WIN32) && defined(HAVE_SYS_FILE_H)
	ftruncate(fd, 0);
	C4LogFile = fdopen(fd, "wb");
#endif
	// save start time
	time(&C4LogStartTime);
	return true;
}
Example #4
0
void C4Console::UpdateNetMenu()
{
	// Active & network hosting check
	if (!Active) return;
	if (!::Network.isHost() || !::Network.isEnabled()) return;
	// Clear old
	ClearNetMenu();
	// Insert menu
	C4ConsoleGUI::AddNetMenu();

	// Host
	StdStrBuf str;
	str.Format(LoadResStr("IDS_MNU_NETHOST"),Game.Clients.getLocalName(),Game.Clients.getLocalID());
	AddNetMenuItemForPlayer(Game.Clients.getLocalID(), str.getData(), C4ConsoleGUI::CO_None);
	// Clients
	for (C4Network2Client *pClient=::Network.Clients.GetNextClient(nullptr); pClient; pClient=::Network.Clients.GetNextClient(pClient))
	{
		if (pClient->isHost()) continue;
		str.Format(LoadResStr(pClient->isActivated() ? "IDS_MNU_NETCLIENT_DEACTIVATE" : "IDS_MNU_NETCLIENT_ACTIVATE"),
		           pClient->getName(), pClient->getID());
		AddNetMenuItemForPlayer(pClient->getID(), str.getData(), pClient->isActivated() ? C4ConsoleGUI::CO_Deactivate : C4ConsoleGUI::CO_Activate);
		str.Format(LoadResStr("IDS_NET_KICKCLIENTEX"), pClient->getName(), pClient->getID());
		AddNetMenuItemForPlayer(pClient->getID(), str.getData(), C4ConsoleGUI::CO_Kick);
	}
	return;
}
bool C4PlayerList::Save(C4Group &hGroup, bool fStoreTiny, const C4PlayerInfoList &rStoreList)
{
	StdStrBuf sTempFilename;
	bool fSuccess = true;
	// Save to external player files and add to group
	for (C4Player *pPlr=First; pPlr; pPlr=pPlr->Next)
	{
		// save only those in the list, and only those with a filename
		C4PlayerInfo *pNfo = rStoreList.GetPlayerInfoByID(pPlr->ID);
		if (!pNfo) continue;
		if (!pNfo->GetFilename() || !*pNfo->GetFilename()) continue;;
		// save over original file?
		bool fStoreOnOriginal = (!fStoreTiny && pNfo->GetType() == C4PT_User);
		// Create temporary file
		sTempFilename.Copy(Config.AtTempPath(pNfo->GetFilename()));
		if (fStoreOnOriginal)
			if (!C4Group_CopyItem(pPlr->Filename, sTempFilename.getData()))
				return false;
		// Open group
		C4Group PlrGroup;
		if (!PlrGroup.Open(sTempFilename.getData(), !fStoreOnOriginal))
			return false;
		// Save player
		if (!pPlr->Save(PlrGroup, true, fStoreOnOriginal)) return false;
		PlrGroup.Close();
		// Add temp file to group
		if (!hGroup.Move(sTempFilename.getData(), pNfo->GetFilename())) return false;
	}
	return fSuccess;
}
Example #6
0
void C4Def::LoadMeshMaterials(C4Group &hGroup, C4DefGraphicsPtrBackup *gfx_backup)
{
	// Load all mesh materials from this folder
	C4DefAdditionalResourcesLoader loader(hGroup);
	hGroup.ResetSearch();
	char MaterialFilename[_MAX_PATH + 1]; *MaterialFilename = 0;
	
	for (const auto &mat : mesh_materials)
	{
		::MeshMaterialManager.Remove(mat, &gfx_backup->GetUpdater());
	}
	mesh_materials.clear();
	while (hGroup.FindNextEntry(C4CFN_DefMaterials, MaterialFilename, NULL, !!*MaterialFilename))
	{
		StdStrBuf material;
		if (hGroup.LoadEntryString(MaterialFilename, &material))
		{
			try
			{
				StdStrBuf buf;
				buf.Copy(hGroup.GetName());
				buf.Append("/"); buf.Append(MaterialFilename);
				auto new_materials = ::MeshMaterialManager.Parse(material.getData(), buf.getData(), loader);
				mesh_materials.insert(new_materials.begin(), new_materials.end());
			}
			catch (const StdMeshMaterialError& ex)
			{
				DebugLogF("Failed to read material script: %s", ex.what());
			}
		}
	}
}
Example #7
0
bool LogSilent(const char *szMessage, bool fConsole) {
  if (!Application.AssertMainThread()) return false;
  // security
  if (!szMessage) return false;

  // add timestamp
  time_t timenow;
  time(&timenow);
  StdStrBuf TimeMessage;
  TimeMessage.SetLength(11 + SLen(szMessage) + 1);
  strftime(TimeMessage.getMData(), 11 + 1, "[%H:%M:%S] ", localtime(&timenow));

  // output until all data is written
  const char *pSrc = szMessage;
  do {
    // timestamp will always be that length
    char *pDest = TimeMessage.getMData() + 11;

    // copy rest of message, skip tags
    CMarkup Markup(false);
    while (*pSrc) {
      Markup.SkipTags(&pSrc);
      // break on crlf
      while (*pSrc == '\r') pSrc++;
      if (*pSrc == '\n') {
        pSrc++;
        break;
      }
      // copy otherwise
      if (*pSrc) *pDest++ = *pSrc++;
    }
    *pDest++ = '\n';
    *pDest = '\0';

#ifdef HAVE_ICONV
    StdStrBuf Line = Languages.IconvSystem(TimeMessage.getData());
#else
    StdStrBuf &Line = TimeMessage;
#endif

    // Save into log file
    if (C4LogFile) {
      fputs(Line.getData(), C4LogFile);
      fflush(C4LogFile);
    }

    // Write to console
    if (fConsole || Game.Verbose) {
#if defined(_DEBUG) && defined(_WIN32)
      // debug: output to VC console
      OutputDebugString(Line.getData());
#endif
      fputs(Line.getData(), stdout);
      fflush(stdout);
    }

  } while (*pSrc);

  return true;
}
Example #8
0
size_t C4Network2IRCClient::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr)
	{
	// Find line seperation
 	const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize()));
	if(!pSep)
		return 0;
	// Check if it's actually correct seperation (rarely the case)
	int iSize = pSep - getBufPtr<char>(rInBuf) + 1,
			iLength = iSize - 1;
	if(iLength && *(pSep - 1) == '\r')
		iLength--;
	// Copy the line
	StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength);
	// Ignore prefix
	const char *pMsg = Buf.getData();
	StdStrBuf Prefix;
	if(*pMsg == ':')
		{
		Prefix.CopyUntil(pMsg + 1, ' ');
		pMsg += Prefix.getLength() + 1;
		}
	// Strip whitespace
	while(*pMsg == ' ')
		pMsg++;
	// Ignore empty message
	if(!*pMsg)
		return iSize;
	// Get command
	StdStrBuf Cmd; Cmd.CopyUntil(pMsg, ' ');
	// Precess command
	const char *szParameters = SSearch(pMsg, " ");
	OnCommand(Prefix.getData(), Cmd.getData(), szParameters ? szParameters : "");
	// Consume the line
	return iSize;
	}
bool C4Network2Res::SetByGroup(C4Group *pGrp, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName, bool fSilent) // by main thread
{
	Clear();
	CStdLock FileLock(&FileCSec);
	// default resource name: relative path
	StdStrBuf sResName;
	if (szResName)
		sResName = szResName;
	else
	{
		StdStrBuf sFullName = pGrp->GetFullName();
		sResName.Copy(Config.AtRelativePath(sFullName.getData()));
	}
	SCopy(pGrp->GetFullName().getData(), szFile, sizeof(szFile)-1);
	// set core
	Core.Set(eType, iResID, sResName.getData(), pGrp->EntryCRC32());
#ifdef C4NET2RES_DEBUG_LOG
	// log
	LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, sResName.getData(), szFile, fTemp ? "temp" : "static");
#endif
	// set data
	fDirty = true;
	fTempFile = fTemp;
	fStandaloneFailed = false;
	fRemoved = false;
	iLastReqTime = time(NULL);
	fLoading = false;
	// ok
	return true;
}
void C4Network2ResDlg::ListItem::Update(const C4Network2Res *pByRes)
{
	// update progress label
	iProgress = pByRes->getPresentPercent();
	if (iProgress < 100)
	{
		StdStrBuf progress;
		progress.Format("%d%%", iProgress);
		if (pProgress)
			pProgress->SetText(progress.getData());
		else
		{
			pProgress = new C4GUI::Label(progress.getData(), GetBounds().Wdt - IconLabelSpacing, 0, ARight);
			pProgress->SetToolTip(LoadResStr("IDS_NET_RESPROGRESS_DESC"));
			AddElement(pProgress);
		}
	}
	else if (pProgress) { delete pProgress; pProgress=NULL; }
	// update disk icon
	if (IsSavePossible())
	{
		if (!pSaveBtn)
		{
			pSaveBtn = new C4GUI::CallbackButtonEx<C4Network2ResDlg::ListItem, C4GUI::IconButton>(C4GUI::Ico_Save, GetToprightCornerRect(16,16,2,1), 0, this, &ListItem::OnButtonSave);
			AddElement(pSaveBtn);
		}
	}
	else if (pSaveBtn)
		delete pSaveBtn;
}
Example #11
0
bool C4Language::Init()
{
	// Clear (to allow clean re-init)
	Clear();

	// Make sure Language.ocg is unpacked (TODO: This won't work properly if Language.ocg is in system data path)
	// Assume for now that Language.ocg is either at a writable location or unpacked already.
	// TODO: Use all Language.c4gs that we find, and merge them.
	// TODO: Use gettext instead?
	StdStrBuf langPath;
	C4Reloc::iterator iter;
	for(iter = Reloc.begin(); iter != Reloc.end(); ++iter)
	{
		langPath.Copy((*iter).strBuf + DirSep + C4CFN_Languages);
		if(ItemExists(langPath.getData()))
		{
			if(DirectoryExists(langPath.getData()))
				break;
			if(C4Group_UnpackDirectory(langPath.getData()))
				break;
		}
	}

	// Break if no language.ocg found
	if(iter != Reloc.end())
	{
		// Look for available language packs in Language.ocg
		C4Group *pPack;
		char strPackFilename[_MAX_FNAME + 1], strEntry[_MAX_FNAME + 1];
		if (PackDirectory.Open(langPath.getData()))
		{
			while (PackDirectory.FindNextEntry("*.ocg", strEntry))
			{
				sprintf(strPackFilename, "%s" DirSep "%s", C4CFN_Languages, strEntry);
				pPack = new C4Group();
				if (pPack->Open(strPackFilename))
				{
					Packs.RegisterGroup(*pPack, true, C4GSCnt_Language, false);
				}
				else
				{
					delete pPack;
				}
			}
		}

		// Now create a pack group for each language pack (these pack groups are child groups
		// that browse along each pack to access requested data)
		for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++)
			PackGroups.RegisterGroup(*(new C4Group), true, C4GSPrio_Base, C4GSCnt_Language);
	}

	// Load language infos by scanning string tables (the engine doesn't really need this at the moment)
	InitInfos();

	// Done
	return true;
}
Example #12
0
void C4Network2IRCClient::OnMessage(bool fNotice, const char *szSender, const char *szTarget, const char *szText)
	{

	// Find channel, if not private.
	C4Network2IRCChannel *pChan = NULL;
	if(!SEqualNoCase(szTarget, Nick.getData()))
		pChan = getChannel(szTarget);

	// CTCP tagged data?
	const char X_DELIM = '\001';
	if(szText[0] == X_DELIM)
		{
		// Process messages (it's very rarely more than one, but the spec allows it)
		const char *pMsg = szText + 1;
		while(*pMsg)
			{
			// Find end
			const char *pEnd = strchr(pMsg, X_DELIM);
			if(!pEnd) pEnd = pMsg + SLen(pMsg);
			// Copy CTCP query/reply, get tag
			StdStrBuf CTCP; CTCP.Copy(pMsg, pEnd - pMsg);
			StdStrBuf Tag; Tag.CopyUntil(CTCP.getData(), ' ');
			const char *szData = SSearch(CTCP.getData(), " ");
			StdStrBuf Sender; Sender.CopyUntil(szSender, '!');
			// Process
			if(SEqualNoCase(Tag.getData(), "ACTION"))
				PushMessage(MSG_Action, szSender, szTarget, szData ? szData : "");
			if(SEqualNoCase(Tag.getData(), "FINGER") && !fNotice)
				{
				StdStrBuf Answer;
				if(Config.Registered())
					{
					Answer = Config.GetRegistrationData("Cuid");
					}
				else
					{
					Answer = LoadResStr("IDS_PRC_UNREGUSER");
					}
				Send("NOTICE", FormatString("%s :%cFINGER %s%c", 
					Sender.getData(), X_DELIM, 
					Answer.getData(),
					X_DELIM).getData());
				}
			if(SEqualNoCase(Tag.getData(), "VERSION") && !fNotice)
				Send("NOTICE", FormatString("%s :%cVERSION " C4ENGINECAPTION ":" C4VERSION ":" C4_OS "%c", 
					Sender.getData(), X_DELIM, X_DELIM).getData());
			if(SEqualNoCase(Tag.getData(), "PING") && !fNotice)
				Send("NOTICE", FormatString("%s :%cPING %s%c", 
					Sender.getData(), X_DELIM, szData, X_DELIM).getData());
			// Get next message
			pMsg = pEnd;
			if(*pMsg == X_DELIM) pMsg++;
			}
		}

	// Standard message (not CTCP tagged): Push
	else
		PushMessage(fNotice ? MSG_Notice : MSG_Message, szSender, szTarget, szText);

	}
bool C4Network2Res::SetByCore(const C4Network2ResCore &nCore, bool fSilent, const char *szAsFilename, int32_t iRecursion) // by main thread
{
	StdStrBuf sFilename;
	// try open local file
	const char *szFilename = szAsFilename ? szAsFilename : GetC4Filename(nCore.getFileName());
	if (SetByFile(szFilename, false, nCore.getType(), nCore.getID(), nCore.getFileName(), fSilent))
	{
		// check contents checksum
		if (Core.getContentsCRC() == nCore.getContentsCRC())
		{
			// set core
			fDirty = true;
			Core = nCore;
			// ok then
			return true;
		}
	}
	// get and search for filename without specified folder (e.g., Castle.ocs when the opened game is Easy.ocf\Castle.ocs)
	const char *szFilenameOnly = GetFilename(szFilename);
	const char *szFilenameC4 = GetC4Filename(szFilename);
	if (szFilenameOnly != szFilenameC4)
	{
		sFilename.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4));
		sFilename.Append(szFilenameOnly);
		if (SetByCore(nCore, fSilent, szFilenameOnly, Config.Network.MaxResSearchRecursion)) return true;
	}
	// if it could still not be set, try within all folders of root (ignoring special folders), and try as file outside the folder
	// but do not recurse any deeper than set by config (default: One folder)
	if (iRecursion >= Config.Network.MaxResSearchRecursion) return false;
	StdStrBuf sSearchPath; const char *szSearchPath;
	if (!iRecursion)
		szSearchPath = Config.General.ExePath.getData();
	else
	{
		sSearchPath.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4));
		szSearchPath = sSearchPath.getData();
	}
	StdStrBuf sNetPath; sNetPath.Copy(Config.Network.WorkPath);
	char *szNetPath = sNetPath.GrabPointer();
	TruncateBackslash(szNetPath);
	sNetPath.Take(szNetPath);
	for (DirectoryIterator i(szSearchPath); *i; ++i)
		if (DirectoryExists(*i))
			if (!*GetExtension(*i)) // directories without extension only
				if (!szNetPath || !*szNetPath || !ItemIdentical(*i, szNetPath)) // ignore network path
				{
					// search for complete name at subpath (e.g. MyFolder\Easy.ocf\Castle.ocs)
					sFilename.Format("%s%c%s", *i, DirectorySeparator, szFilenameC4);
					if (SetByCore(nCore, fSilent, sFilename.getData(), iRecursion + 1))
						return true;
				}
	// file could not be found locally
	return false;
}
Example #14
0
bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg)
	{
	// name by file
	Name.Copy(GetFilenameOnly(szFilename));
#if defined(_WIN32) && !defined(HAVE_FREETYPE)
	// check whether group is directory or packed
	if (!hGrp.IsPacked())
		{
		// it's open: use the file directly
		SCopy(hGrp.GetFullName().getData(), FileName, _MAX_PATH);
		AppendBackslash(FileName);
		SAppend(szFilename, FileName);
		if (!FileExists(FileName)) { *FileName=0; return false; }
		fIsTempFile = false;
		}
	else
		{
		// it's packed: extract to temp path
		SCopy(rCfg.AtTempPath(szFilename), FileName, _MAX_PATH);
		// make sure the filename is not in use, in case multiple instances of the engine are run
		if (FileExists(FileName))
			{
			RemoveExtension(FileName);
			StdStrBuf sNewFilename;
			for (int i=0; i<1000; ++i)
				{
				sNewFilename.Format("%s%x", FileName, (int)rand());
				if (*GetExtension(szFilename))
					{
					sNewFilename.AppendChar('.');
					sNewFilename.Append(GetExtension(szFilename));
					}
				if (!FileExists(sNewFilename.getData())) break;
				}
			SCopy(sNewFilename.getData(), FileName, _MAX_PATH);
			}
		if (!hGrp.ExtractEntry(szFilename, FileName)) { *FileName=0; return false; }
		fIsTempFile = true;
		}
	// add the font resource
	//if (!AddFontResourceEx(FileName, FR_PRIVATE, NULL)) requires win2k
	if (!AddFontResource(FileName))
		{
		if (fIsTempFile) EraseFile(FileName);
		*FileName='\0';
		return false;
		}
#else
	if (!hGrp.LoadEntry(szFilename, Data)) return false;
#endif
	// success
	return true;
	}
Example #15
0
void C4StartupMainDlg::OnNetJoin(const StdStrBuf &rsHostAddress)
{
	// no IP given: No join
	if (!rsHostAddress || !*rsHostAddress.getData()) return;
	// set default startup parameters
	*Game.ScenarioFilename=0;
	SCopy("Objects.ocd", Game.DefinitionFilenames);
	Game.NetworkActive = true;
	Game.fLobby = true;
	Game.fObserve = false;
	SCopy(rsHostAddress.getData(), Game.DirectJoinAddress, sizeof(Game.DirectJoinAddress)-1);
	// start with this set!
	Application.OpenGame();
}
Example #16
0
GLenum C4Shader::AddTexCoord(const char *szName)
{
	// Make sure we have enough space
	assert(iTexCoords < C4Shader_MaxTexCoords);
	if(iTexCoords >= C4Shader_MaxTexCoords)
		return -1;

	// Add slices
	StdStrBuf Code = FormatString("gl_TexCoord[%d] = gl_MultiTexCoord%d;\n", iTexCoords, iTexCoords);
	AddVertexSlice(C4Shader_Vertex_TexCoordPos, Code.getData());
	Code.Format("#define %s gl_TexCoord[%d]\n", szName, iTexCoords);
	AddFragmentSlice(-1, Code.getData());

	return GL_TEXTURE0 + iTexCoords++;
}
Example #17
0
int C4Shader::ParsePosition(const char *szWhat, const char **ppPos)
{
	const char *pPos = *ppPos;
	while (isspace(*pPos)) pPos++;

	// Expect a name
	const char *pStart = pPos;
	while (isalnum(*pPos)) pPos++;
	StdStrBuf Name; Name.Copy(pStart, pPos - pStart);

	// Lookup name
	int iPosition = -1;
	for (int i = 0; i < sizeof(C4SH_PosNames) / sizeof(*C4SH_PosNames); i++) {
		if (SEqual(Name.getData(), C4SH_PosNames[i].Name)) {
			iPosition = C4SH_PosNames[i].Position;
			break;
		}
	}
	if (iPosition == -1) {
		ShaderLogF("  gl: Unknown slice position in %s: %s", szWhat, Name.getData());
		return -1;
	}

	// Add modifier
	while (isspace(*pPos)) pPos++;
	if (*pPos == '+') {
		int iMod, iModLen;
		if (!sscanf(pPos+1, "%d%n", &iMod, &iModLen)) {
			ShaderLogF("  gl: Invalid slice modifier in %s", szWhat);
			return -1;
		}
		iPosition += iMod;
		pPos += 1+iModLen;
	}
	if (*pPos == '-') {
		int iMod, iModLen;
		if (!sscanf(pPos+1, "%d%n", &iMod, &iModLen)) {
			ShaderLogF("  gl: Invalid slice modifier in %s", szWhat);
			return -1;
		}
		iPosition -= iMod;
		pPos += 1+iModLen;
	}

	// Everything okay!
	*ppPos = pPos;
	return iPosition;
}
Example #18
0
bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName)
	{
#ifdef C4ENGINE
	// build file in memory
	StdStrBuf sTexMapFile;
	// add desc
	sTexMapFile.Append("# Automatically generated texture map" LineFeed);
	sTexMapFile.Append("# Contains material-texture-combinations added at runtime" LineFeed);
	// add overload-entries
	if (fOverloadMaterials) sTexMapFile.Append("# Import materials from global file as well" LineFeed "OverloadMaterials" LineFeed);
	if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well" LineFeed "OverloadTextures" LineFeed);
	sTexMapFile.Append(LineFeed);
	// add entries
	for (int32_t i = 0; i < C4M_MaxTexIndex; i++)
		if (!Entry[i].isNull())
			{
			// compose line
			sTexMapFile.AppendFormat("%d=%s-%s" LineFeed, i, Entry[i].GetMaterialName(), Entry[i].GetTextureName());
			}
	// create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers
	size_t iBufSize = sTexMapFile.getLength();
	BYTE *pBuf = new BYTE[iBufSize];
	memcpy(pBuf, sTexMapFile.getData(), iBufSize);
	// add to group
	bool fSuccess = !!hGroup.Add(szEntryName, pBuf, iBufSize, false, true);
	if (!fSuccess) delete [] pBuf;
	// done
	return fSuccess;
#else
	return FALSE;
#endif
	}
bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize)
{
#ifndef USE_CONSOLE
	// safety
	if (!szFontFace || !*szFontFace || iFontSize<1 || SLen(szFontFace)>=static_cast<int>(sizeof Config.General.RXFontName)) return false;
	// first, check if the selected font can be created at all
	// check regular font only - there's no reason why the other fonts couldn't be created
	CStdFont TestFont;
	if (!::FontLoader.InitFont(&TestFont, szFontFace, C4FontLoader::C4FT_Main, iFontSize, &::GraphicsResource.Files))
		return false;
	// OK; reinit all fonts
	StdStrBuf sOldFont; sOldFont.Copy(Config.General.RXFontName);
	int32_t iOldFontSize = Config.General.RXFontSize;
	SCopy(szFontFace, Config.General.RXFontName);
	Config.General.RXFontSize = iFontSize;
	if (!::GraphicsResource.InitFonts() || !C4Startup::Get()->Graphics.InitFonts())
	{
		// failed :o
		// shouldn't happen. Better restore config.
		SCopy(sOldFont.getData(), Config.General.RXFontName);
		Config.General.RXFontSize = iOldFontSize;
		return false;
	}
#endif
	// save changes
	return true;
}
bool C4DownloadDlg::DownloadFile(const char *szDLType, C4GUI::Screen *pScreen, const char *szURL, const char *szSaveAsFilename, const char *szNotFoundMessage)
{
	// log it
	LogF(LoadResStr("IDS_PRC_DOWNLOADINGFILE"), szURL);
	// show download dialog
	C4DownloadDlg *pDlg = new C4DownloadDlg(szDLType);
	if (!pDlg->ShowModal(pScreen, szURL, szSaveAsFilename))
	{
		// show an appropriate error
		const char *szError = pDlg->GetError();
		if (!szError || !*szError) szError = LoadResStr("IDS_PRC_UNKOWNERROR");
		StdStrBuf sError;
		sError.Format(LoadResStr("IDS_PRC_DOWNLOADERROR"), GetFilename(szURL), szError);
		// it's a 404: display extended message
		if (SSearch(szError, "404") && szNotFoundMessage)
			{ sError.Append("|"); sError.Append(szNotFoundMessage); }
		// display message
		pScreen->ShowMessageModal(sError.getData(), FormatString(LoadResStr("IDS_CTL_DL_TITLE"), szDLType).getData(), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error, NULL);
		delete pDlg;
		return false;
	}
	LogF(LoadResStr("IDS_PRC_DOWNLOADCOMPLETE"), szURL);
	delete pDlg;
	return true;
}
Example #21
0
bool ShaderLogF(const char *strMessage ...)
{
	va_list args; va_start(args, strMessage);
	StdStrBuf Buf;
	Buf.FormatV(strMessage, args);
	return ShaderLog(Buf.getData());
}
static int RunFile(const char * filename, bool checkOnly)
{
	C4Group File;
	if (!File.Open(GetWorkingDirectory()))
	{
		fprintf(stderr, "Open failed: %s\n", File.GetError());
		return 1;
	}

	// get scripts
	StdStrBuf fn;
	File.ResetSearch();
	if (!File.FindNextEntry(filename, &fn))
	{
		fprintf(stderr, "FindNextEntry failed: %s\n", File.GetError());
		return 1;
	}

	InitializeC4Script();
	GameScript.Load(File, fn.getData(), nullptr, nullptr);
	if (!checkOnly)
		RunLoadedC4Script();
	ClearC4Script();
	return ScriptEngine.errCnt;
}
Example #23
0
void C4StartupMainDlg::OnNetJoin(const StdStrBuf &rsHostAddress) {
#ifdef NETWORK
  // no IP given: No join
  if (!rsHostAddress || !*rsHostAddress.getData()) return;
  // set default startup parameters
  *Game.ScenarioFilename = 0;
  SCopy("Objects.c4d", Game.DefinitionFilenames);
  Game.NetworkActive = TRUE;
  Game.fLobby = TRUE;
  Game.fObserve = FALSE;
  SCopy(rsHostAddress.getData(), Game.DirectJoinAddress,
        sizeof(Game.DirectJoinAddress) - 1);
  // start with this set!
  C4Startup::Get()->Start();
#endif
}
bool C4GameSave::SaveDesc(C4Group &hToGroup)
{
	// Unfortunately, there's no way to prealloc the buffer in an appropriate size
	StdStrBuf sBuffer;

	// Header
	sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", 0 /*FIXME: a number for UTF-8 here*/);
	sBuffer.Append(LineFeed);

	// Scenario title
	sBuffer.AppendFormat("\\uc1\\pard\\ulnone\\b\\f0\\fs20 %s\\par",Game.ScenarioTitle.getData());
	sBuffer.Append(LineFeed "\\b0\\fs16\\par" LineFeed);

	// OK; each specializations has its own desc format
	WriteDesc(sBuffer);

	// End of file
	sBuffer.Append(LineFeed "}" LineFeed);

	// Generate Filename
	StdStrBuf sFilename; char szLang[3];
	SCopyUntil(Config.General.Language, szLang, ',', 2);
	sFilename.Format(C4CFN_ScenarioDesc,szLang);

	// Save to file
	return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true);
}
Example #25
0
void C4GameOverDlg::SetNetResult(const char *szResultString, C4RoundResults::NetResult eResultType, size_t iPendingStreamingData, bool fIsStreaming)
	{
	// add info about pending streaming data
	StdStrBuf sResult(szResultString);
	if (fIsStreaming)
		{
		sResult.AppendChar('|');
		sResult.AppendFormat("[!]Transmitting record to league server... (%d kb remaining)", int(iPendingStreamingData/1024));
		}
	// message linebreak into box
	StdStrBuf sBrokenResult;
	C4GUI::GetRes()->TextFont.BreakMessage(sResult.getData(), pNetResultLabel->GetBounds().Wdt, &sBrokenResult, true);
	pNetResultLabel->SetText(sBrokenResult.getData(), false);
	// all done?
	if (eResultType != C4RoundResults::NR_None && !fIsStreaming)
		{
		// a final result is determined and all streaming data has been transmitted
		fIsNetDone = true;
		}
	// network error?
	if (eResultType == C4RoundResults::NR_NetError)
		{
		// disconnected. Do not show winners/losers
		for (int32_t i=0; i<iPlrListCount; ++i) ppPlayerLists[i]->SetMode(C4PlayerInfoListBox::PILBM_EvaluationNoWinners);
		}
	}
Example #26
0
StdStrBuf C4FileSelDlg::GetSelection(const char *szFixedSelection,
                                     bool fFilenameOnly) const {
  StdStrBuf sResult;
  if (!IsMultiSelection()) {
    // get single selected file for single selection dlg
    if (pSelection)
      sResult.Copy(fFilenameOnly ? GetFilename(pSelection->GetFilename())
                                 : pSelection->GetFilename());
  } else {
    // force fixed selection first
    if (szFixedSelection) sResult.Append(szFixedSelection);
    //  get ';'-seperated list for multi selection dlg
    for (ListItem *pFileItem =
             static_cast<ListItem *>(pFileListBox->GetFirst());
         pFileItem; pFileItem = static_cast<ListItem *>(pFileItem->GetNext()))
      if (pFileItem->IsChecked()) {
        const char *szAppendFilename = pFileItem->GetFilename();
        if (fFilenameOnly) szAppendFilename = GetFilename(szAppendFilename);
        // prevent adding entries twice (especially those from the fixed
        // selection list)
        if (!SIsModule(sResult.getData(), szAppendFilename)) {
          if (sResult.getLength()) sResult.AppendChar(';');
          sResult.Append(szAppendFilename);
        }
      }
  }
  return sResult;
}
Example #27
0
bool C4MaterialMap::LoadEnumeration(C4Group &hGroup)
{
	// Load enumeration map (from savegame), succeed if not present
	StdStrBuf mapbuf;
	if (!hGroup.LoadEntryString(C4CFN_MatMap, &mapbuf)) return true;

	// Sort material array by enumeration map, fail if some missing
	const char *csearch;
	char cmatname[C4M_MaxName+1];
	int32_t cmat=0;
	if (!(csearch = SSearch(mapbuf.getData(),"[Enumeration]"))) { return false; }
	csearch=SAdvanceSpace(csearch);
	while (IsIdentifier(*csearch))
	{
		SCopyIdentifier(csearch,cmatname,C4M_MaxName);
		if (!SortEnumeration(cmat,cmatname))
		{
			// Output error message!
			return false;
		}
		cmat++;
		csearch+=SLen(cmatname);
		csearch=SAdvanceSpace(csearch);
	}

	return true;
}
bool C4PlayerInfoCore::Load(C4Group &hGroup)
{
	// New version
	StdStrBuf Source;
	if (hGroup.LoadEntryString(C4CFN_PlayerInfoCore,&Source))
	{
		// Compile
		StdStrBuf GrpName = hGroup.GetFullName(); GrpName.Append(DirSep C4CFN_PlayerInfoCore);
		if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Source, GrpName.getData()))
			return false;
		// Pref for AutoContextMenus is still undecided: default by player's control style
		if (OldPrefAutoContextMenu == -1)
			OldPrefAutoContextMenu = OldPrefControlStyle;
		// Determine true color from indexed pref color
		if (!PrefColorDw)
			PrefColorDw = GetPrefColorValue(PrefColor);
		// Validate colors
		PrefColorDw &= 0xffffff;
		PrefColor2Dw &= 0xffffff;
		// Validate name
		C4Markup::StripMarkup(PrefName);
		// Success
		return true;
	}

	// Old version no longer supported - sorry
	return false;
}
Example #29
0
void C4Console::PlayerJoin()
{
	// Get player file name(s)
	StdCopyStrBuf c4pfile("");
	if (!FileSelect(&c4pfile,
	                "OpenClonk Player\0*.ocp\0\0",
	                OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER
	               )) return;

	// Multiple players
	if (DirectoryExists(c4pfile.getData()))
	{
		const char *cptr = c4pfile.getData() + SLen(c4pfile.getData()) + 1;
		while (*cptr)
		{
			StdStrBuf f;
			f.Copy(c4pfile.getData());
			f.AppendBackslash(); f.Append(cptr);
			cptr += SLen(cptr)+1;
			::Players.JoinNew(f.getData());
		}
	}
	// Single player
	else
	{
		::Players.JoinNew(c4pfile.getData());
	}
}
Example #30
0
bool C4TexMapEntry::Init()
{
	// Find material
	iMaterialIndex = ::MaterialMap.Get(Material.getData());
	if (!MatValid(iMaterialIndex))
	{
		DebugLogF("Error initializing material %s-%s: Invalid material!", Material.getData(), Texture.getData());
		return false;
	}
	pMaterial = &::MaterialMap.Map[iMaterialIndex];
	// Find texture
	StdStrBuf FirstTexture;
	FirstTexture.CopyUntil(Texture.getData(), '-');
	C4Texture * sfcTexture = ::TextureMap.GetTexture(FirstTexture.getData());
	if (!sfcTexture)
	{
		DebugLogF("Error initializing material %s-%s: Invalid texture!", Material.getData(), FirstTexture.getData());
		Clear();
		return false;
	}
	// Get overlay properties
	int32_t iOverlayType=pMaterial->OverlayType;
	int32_t iZoom=0;
	if (iOverlayType & C4MatOv_Exact) iZoom=1;
	if (iOverlayType & C4MatOv_HugeZoom) iZoom=4;
	// Create pattern
	MatPattern.Set(sfcTexture->Surface32, iZoom);
	return true;
}