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]);
		}

	}
Example #2
0
void C4Language::LoadInfos(C4Group &hGroup)
{
	char strEntry[_MAX_FNAME + 1];
	char *strTable;
	// Look for language string tables
	hGroup.ResetSearch();
	while (hGroup.FindNextEntry(C4CFN_Language, strEntry))
		// For now, we will only load info on the first string table found for a given
		// language code as there is currently no handling for selecting different string tables
		// of the same code - the system always loads the first string table found for a given code
		if (!FindInfo(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2))
			// Load language string table
			if (hGroup.LoadEntry(strEntry, &strTable, 0, 1))
			{
				// New language info
				C4LanguageInfo *pInfo = new C4LanguageInfo;
				// Get language code by entry name
				SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2);
				SCapitalize(pInfo->Code);
				// Get language name, info, fallback from table
				CopyResStr("IDS_LANG_NAME", strTable, pInfo->Name);
				CopyResStr("IDS_LANG_INFO", strTable, pInfo->Info);
				CopyResStr("IDS_LANG_FALLBACK", strTable, pInfo->Fallback);
				// Safety: pipe character is not allowed in any language info string
				SReplaceChar(pInfo->Name, '|', ' ');
				SReplaceChar(pInfo->Info, '|', ' ');
				SReplaceChar(pInfo->Fallback, '|', ' ');
				// Delete table
				delete [] strTable;
				// Add info to list
				pInfo->Next = Infos;
				Infos = pInfo;
			}
}
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 #4
0
void C4GraphicsOverlay::Read(const char **ppInput)
{
	// deprecated
	assert(false && "C4GraphicsOverlay::Read: deprecated");
#if 0
	const char *szReadFrom = *ppInput;
	// defaults
	eMode = MODE_None; pSourceGfx = NULL; *Action=0; dwBlitMode = 0; iPhase = 0; iID=0;
	// read ID
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &iID);
	// read C4ID::Gfxname
	int32_t iLineLength = SLen(szReadFrom);
	// not C4ID::Name?
	if (iLineLength < 6 || szReadFrom[4]!=':' || szReadFrom[5]!=':')
	{
		DebugLog("C4Compiler error: Malformed graphics overlay definition!");
		return;
	}
	// get ID
	char id[5]; SCopy(szReadFrom, id, 4); szReadFrom += 6;
	C4Def *pSrcDef = ::Definitions.ID2Def(C4Id(id)); // defaults to NULL for unloaded def
	if (pSrcDef)
	{
		char GfxName[C4MaxName+1];
		SCopyUntil(szReadFrom, GfxName, ',', C4MaxName);
		szReadFrom += strlen(GfxName); if (*szReadFrom) ++szReadFrom;
		// get graphics - "C4ID::" leads to *szLine == NULL, and thus the default graphic of pSrcDef!
		pSourceGfx = pSrcDef->Graphics.Get(GfxName);
	}
	// read mode
	DWORD dwRead;
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &dwRead); eMode = (Mode) dwRead;
	// read action
	SCopyUntil(szReadFrom, Action, ',', C4MaxName);
	szReadFrom += strlen(Action); if (*szReadFrom) ++szReadFrom;
	// read blit mode
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &dwBlitMode);
	// read phase
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &iPhase);
	// read transform
	if (*szReadFrom) ++szReadFrom; // '('
	int32_t iScanCnt = sscanf(szReadFrom, "%f,%f,%f,%f,%f,%f,%d",
	                          &Transform.mat[0], &Transform.mat[1], &Transform.mat[2],
	                          &Transform.mat[3], &Transform.mat[4], &Transform.mat[5], &Transform.FlipDir);
	if (iScanCnt != 7) { DebugLog("C4Compiler: malformed C4CV_Transform"); }
	iScanCnt = SCharPos(')', szReadFrom); if (iScanCnt>=0) szReadFrom += iScanCnt+1;
	// assign ptr immediately after read overlay
	*ppInput = szReadFrom;
	// update used facet according to read data
	UpdateFacet();
#endif
}
Example #5
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 #6
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 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;
}
Example #8
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);

	}
Example #9
0
String::String(StringBuffer& b)
{
	int l = b.GetLength();
	if(l <= 14) {
		Zero();
		memcpy(chr, b.begin, l);
		SLen() = l;
		b.Free();
	}
	else {
		ptr = b.begin;
		ptr[l] = 0;
		SLen() = 15;
		LLen() = l;
		chr[KIND] = min(b.GetAlloc(), 255);
	}
	b.Zero();
}
Example #10
0
String::String(StringBuffer& b)
{
	int l = b.GetLength();
	if(l <= 14) {
		Zero();
		memcpy(chr, b.begin, l);
		SLen() = l;
		b.Free();
	}
	else {
		ptr = b.begin;
		ptr[l] = 0;
		SLen() = 15;
		LLen() = l;
		chr[KIND] = b.limit - b.begin == 31 ? MEDIUM : REF;
	}
	b.Zero();
}
Example #11
0
bool C4ChatInputDialog::KeyCompleteNick() {
  if (!pEdit) return false;
  char IncompleteNick[256 + 1];
  // get current word in edit
  if (!pEdit->GetCurrentWord(IncompleteNick, 256)) return false;
  if (!*IncompleteNick) return false;
  C4Player *plr = Game.Players.First;
  while (plr) {
    // Compare name and input
    if (SEqualNoCase(plr->GetName(), IncompleteNick, SLen(IncompleteNick))) {
      pEdit->InsertText(plr->GetName() + SLen(IncompleteNick), true);
      return true;
    } else
      plr = plr->Next;
  }
  // no match found
  return false;
}
Example #12
0
void String0::Cat(const char *s, int len)
{
	if(IsSmall()) {
		if(SLen() + len < 14) {
			memcpy(chr + SLen(), s, len);
			SLen() += len;
			chr[SLen()] = 0;
			return;
		}
	}
	else
		if((int)LLen() + len < LAlloc() && !IsSharedRef()) {
			memcpy(ptr + LLen(), s, len);
			LLen() += len;
			ptr[LLen()] = 0;
			return;
		}
	Insert(GetCount(), len, s);
}
Example #13
0
void C4ValueMapNames::ChangeNameList(const char **pnNames, int32_t *pnExtra, int32_t nSize)
{
	// safe old name list
	char **pOldNames = pNames;
	int32_t *pOldExtra = pExtra;
	int32_t iOldSize = iSize;
	

	// create new lists
	pNames = new char *[nSize];
	pExtra = new int32_t [nSize];

	// copy names
	int32_t i;
	for(i = 0; i < nSize; i++)
	{
		pNames[i] = new char [SLen(pnNames[i]) + 1];
		SCopy(pnNames[i], pNames[i], SLen(pnNames[i]) + 1);
		if(pnExtra) pExtra[i] = pnExtra[i];
	}

	if(!pnExtra)
		ZeroMem(pExtra, sizeof (*pExtra) * nSize);

	// set new size 
	iSize = nSize;

	// call OnNameListChanged list for all "child" lists
	C4ValueMapData *pAktData = pFirst;
	while(pAktData)
	{
		pAktData->OnNameListChanged(const_cast<const char **>(pOldNames), iOldSize);
		pAktData = pAktData->pNext;
	}

	// delete old list
	for(i = 0; i < iOldSize; i++)
		delete[] pOldNames[i];
	delete[] pOldNames;
	delete[] pOldExtra;

	// ok.
}
Example #14
0
void String0::Set(const char *s, int len)
{
	w[0] = w[1] = w[2] = w[3] = 0;
	switch(len) {
	#define MOV(x) case x: chr[x - 1] = s[x - 1];
		MOV(14) MOV(13) MOV(12) MOV(11) MOV(10) MOV(9) MOV(8)
		MOV(7) MOV(6) MOV(5) MOV(4) MOV(3) MOV(2) MOV(1)
	case 0:
		SLen() = len;
		break;
	default:
		char *p = Alloc(len, chr[KIND]);
		memcpy(p, s, len);
		p[len] = 0;
		ptr = p;
		LLen() = len;
		SLen() = 15;
	};
}
Example #15
0
void String0::Remove(int pos, int count)
{
	ASSERT(pos >= 0 && count >= 0 && pos + count <= GetCount());
	UnShare();
	char *s = (char *)Begin();
	memmove(s + pos, s + pos + count, GetCount() - pos - count + 1);
	if(IsSmall())
		SetSLen(SLen() - count);
	else
		LLen() -= count;
}
Example #16
0
bool C4MaterialMap::SaveEnumeration(C4Group &hGroup)
{
	char *mapbuf = new char [1000];
	mapbuf[0]=0;
	SAppend("[Enumeration]",mapbuf); SAppend(LineFeed,mapbuf);
	for (int32_t cnt=0; cnt<Num; cnt++)
	{
		SAppend(Map[cnt].Name,mapbuf);
		SAppend(LineFeed,mapbuf);
	}
	return hGroup.Add(C4CFN_MatMap,mapbuf,SLen(mapbuf),false,true);
}
	static bool Helper(const char *szPath)
	{
		if (szPath[SLen(szPath)-1] == '.')
			return false;
		if (iSize > iMaxSize)
			return false;
		if (DirectoryExists(szPath))
			ForEachFile(szPath, &Helper);
		else if (FileExists(szPath))
			iSize += FileSize(szPath);
		return true;
	}
Example #18
0
void String0::LCat(int c)
{
	if(IsSmall()) {
		qword *x = (qword *)MAlloc_S();
		x[0] = q[0];
		x[1] = q[1];
		LLen() = SLen();
		SLen() = 15;
		chr[KIND] = MEDIUM;
		qptr = x;
	}
	int l = LLen();
	if(IsRef() ? !IsShared() && l < (int)Ref()->alloc : l < 31) {
		ptr[l] = c;
		ptr[LLen() = l + 1] = 0;
	}
	else {
		char *s = Insert(l, 1, NULL);
		s[0] = c;
		s[1] = 0;
	}
}
Example #19
0
force_inline
void String0::Set(const char *s, int len)
{
	Clear();
	if(len < 14) {
		SVO_MEMCPY(chr, s, len);
		SLen() = len;
		Dsyn();
		return;
	}
	SetL(s, len);
	Dsyn();
}
bool C4RankSystem::Check(int iRank, const char  *szDefRankName)
{
#ifdef _WIN32
	char keyname[30];
	sprintf(keyname,"Rank%03d",iRank);
	if (!GetRegistryString(Register,keyname).isNull())
		return false;
	if (!szDefRankName || (SLen(szDefRankName)>C4MaxName))
		return false;
	return SetRegistryString(Register,keyname,szDefRankName);
#else
	return true;
#endif
}
void SetClientPrefix(char *szFilename, const char *szClient)
{
	char szTemp[1024+1];
	// Compose prefix
	char szPrefix[1024+1];
	SCopy(szClient,szPrefix); SAppendChar('-',szPrefix);
	// Prefix already set?
	SCopy(GetFilename(szFilename),szTemp,SLen(szPrefix));
	if (SEqualNoCase(szTemp,szPrefix)) return;
	// Insert prefix
	SCopy(GetFilename(szFilename),szTemp);
	SCopy(szPrefix,GetFilename(szFilename));
	SAppend(szTemp,szFilename);
}
Example #22
0
BOOL C4RankSystem::Check(int iRank, const char  *szDefRankName)
	{
#ifdef _WIN32
	char rankname[C4MaxName+1],keyname[30];
	sprintf(keyname,"Rank%03d",iRank);
	if (GetRegistryString(Register,keyname,rankname,C4MaxName+1))
		return FALSE;
	if (!szDefRankName || (SLen(szDefRankName)>C4MaxName))
		return FALSE;
	return SetRegistryString(Register,keyname,szDefRankName);
#else
	return TRUE;
#endif
	}
Example #23
0
char *String0::Insert(int pos, int count, const char *s)
{
	ASSERT(pos >= 0 && count >= 0 && pos <= GetCount());
	int len = GetCount();
	int newlen = len + count;
	char *str = (char *)Begin();
	if(newlen < GetAlloc() && !IsSharedRef()/* && !(s >= str && s <= str + len)*/) {
		if(s >= str + pos && s <= str + len)
			s += count;
		if(pos < len)
			memmove(str + pos + count, str + pos, len - pos);
		if(IsSmall())
			SLen() = newlen;
		else
			LLen() = newlen;
		str[newlen] = 0;
		if(s)
			memcpy(str + pos, s, count);
		return str + pos;
	}
	char kind;
	char *p = Alloc(max(2 * len, newlen), kind);
	if(pos > 0)
		memcpy(p, str, pos);
	if(pos < len)
		memcpy(p + pos + count, str + pos, len - pos);
	if(s)
		memcpy(p + pos, s, count);
	p[newlen] = 0;
	Free();
	ptr = p;
	LLen() = newlen;
	SLen() = 15;
	chr[KIND] = kind;
	return ptr + pos;
}
Example #24
0
bool EraseItemSafe(const char *szFilename)
{
	char Filename[_MAX_PATH+1];
	SCopy(szFilename, Filename, _MAX_PATH);
	Filename[SLen(Filename)+1]=0;
	SHFILEOPSTRUCTW shs;
	shs.hwnd=0;
	shs.wFunc=FO_DELETE;
	shs.pFrom=GetWideChar(Filename);
	shs.pTo=NULL;
	shs.fFlags=FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
	shs.fAnyOperationsAborted=false;
	shs.hNameMappings=0;
	shs.lpszProgressTitle=NULL;
	return !SHFileOperationW(&shs);
}
void C4GraphicsSystem::FlashMessage(const char *szMessage)
	{
	// Store message
	SCopy(szMessage, FlashMessageText, C4MaxTitle);
	// Calculate message time
	FlashMessageTime = SLen(FlashMessageText) * 2;
	// Initial position
	FlashMessageX = -1; 
	FlashMessageY = 10;
	// Upper board active: stay below upper board
	if (Config.Graphics.UpperBoard)
		FlashMessageY += C4UpperBoardHeight;
	// More than one viewport: try to stay below portraits etc.
	if (GetViewportCount() > 1)
		FlashMessageY += 64;
	// New flash message: redraw background (might be drawing one message on top of another)
	InvalidateBg();
	}
Example #26
0
void C4FileMonitor::HandleNotify(const char *szDir, const _FILE_NOTIFY_INFORMATION *pNotify)
{
	// Get filename length
	UINT iCodePage = CP_UTF8;
	int iFileNameBytes = WideCharToMultiByte(iCodePage, 0,
	                     pNotify->FileName, pNotify->FileNameLength / 2, NULL, 0, NULL, NULL);
	// Set up filename buffer
	StdCopyStrBuf Path(szDir);
	Path.AppendChar(DirectorySeparator);
	Path.Grow(iFileNameBytes);
	char *pFilename = Path.getMPtr(SLen(Path.getData()));
	// Convert filename
	int iWritten = WideCharToMultiByte(iCodePage, 0,
	                                   pNotify->FileName, pNotify->FileNameLength / 2,
	                                   pFilename, iFileNameBytes,
	                                   NULL, NULL);
	if (iWritten != iFileNameBytes)
		Path.Shrink(iFileNameBytes+1);
	// Send notification
	Application.InteractiveThread.PushEvent(Ev_FileChange, Path.GrabPointer());
}
Example #27
0
void C4Network2IRCClient::OnCommand(const char *szSender, const char *szCommand, const char *szParameters)
	{
	CStdLock Lock(&CSec);
	// Numeric command?
	if(isdigit((unsigned char)*szCommand) && SLen(szCommand) == 3)
		{
		OnNumericCommand(szSender, atoi(szCommand), szParameters);
		return;
		}
	// Sender's nick
	StdStrBuf SenderNick;
	if(szSender) SenderNick.CopyUntil(szSender, '!');
	// Ping?
	if(SEqualNoCase(szCommand, "PING"))
		Send("PONG", szParameters);
	// Message?
	if(SEqualNoCase(szCommand, "NOTICE") || SEqualNoCase(szCommand, "PRIVMSG"))
		{
		// Get target
		StdStrBuf Target = ircExtractPar(&szParameters);
		// Get text
		StdStrBuf Text = ircExtractPar(&szParameters);
		// Process message
		OnMessage(SEqualNoCase(szCommand, "NOTICE"), szSender, Target.getData(), Text.getData());
		}
	// Channel join?
	if(SEqualNoCase(szCommand, "JOIN"))
		{
		// Get channel
		StdStrBuf Channel = ircExtractPar(&szParameters);
		C4Network2IRCChannel *pChan = AddChannel(Channel.getData());
		// Add user
		pChan->OnJoin(SenderNick.getData());
		// Myself?
		if(SenderNick == Nick)
			PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_YOUHAVEJOINEDCHANNEL"), Channel.getData()).getData());
		else
			PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_HASJOINEDTHECHANNEL"), SenderNick.getData()).getData());
		}
	// Channel part?
	if(SEqualNoCase(szCommand, "PART"))
		{
		// Get channel
		StdStrBuf Channel = ircExtractPar(&szParameters);
		C4Network2IRCChannel *pChan = AddChannel(Channel.getData());
		// Get message
		StdStrBuf Comment = ircExtractPar(&szParameters);
		// Remove user
		pChan->OnPart(SenderNick.getData(), Comment.getData());
		// Myself?
		if(SenderNick == Nick)
			{
			DeleteChannel(pChan);
			PushMessage(MSG_Status, szSender, Nick.getData(), FormatString(LoadResStr("IDS_MSG_YOUHAVELEFTCHANNEL"), Channel.getData(), Comment.getData()).getData());
			}
		else
			PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_HASLEFTTHECHANNEL"), SenderNick.getData(), Comment.getData()).getData());
		}
	// Kick?
	if(SEqualNoCase(szCommand, "KICK"))
		{
		// Get channel
		StdStrBuf Channel = ircExtractPar(&szParameters);
		C4Network2IRCChannel *pChan = AddChannel(Channel.getData());
		// Get kicked user
		StdStrBuf Kicked = ircExtractPar(&szParameters);
		// Get message
		StdStrBuf Comment = ircExtractPar(&szParameters);
		// Remove user
		pChan->OnKick(Kicked.getData(), Comment.getData());
		// Myself? 
		if(Kicked == Nick)
			{
			DeleteChannel(pChan);
			PushMessage(MSG_Status, szSender, Nick.getData(), FormatString(LoadResStr("IDS_MSG_YOUWEREKICKEDFROMCHANNEL"), Channel.getData(), Comment.getData()).getData());
			}
		else
			PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_WASKICKEDFROMTHECHANNEL"), Kicked.getData(), Comment.getData()).getData());
		}
	// Quit?
	if(SEqualNoCase(szCommand, "QUIT"))
		{
		// Get comment
		StdStrBuf Comment = ircExtractPar(&szParameters);
		// Format status message
    StdStrBuf Message = FormatString(LoadResStr("IDS_MSG_HASDISCONNECTED"), SenderNick.getData(), Comment.getData());
    // Remove him from all channels
    for(C4Network2IRCChannel *pChan = pChannels; pChan; pChan = pChan->Next)
      if(pChan->getUser(SenderNick.getData()))
        {
        pChan->OnPart(SenderNick.getData(), "Quit");
        PushMessage(MSG_Status, szSender, pChan->getName(), Message.getData());
        }
		}
	// Topic change?
	if(SEqualNoCase(szCommand, "TOPIC"))
		{
		// Get channel and topic
		StdStrBuf Channel = ircExtractPar(&szParameters);
		StdStrBuf Topic = ircExtractPar(&szParameters);
		// Set topic
		AddChannel(Channel.getData())->OnTopic(Topic.getData());
		// Message
		PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_CHANGESTHETOPICTO"), SenderNick.getData(), Topic.getData()).getData());
		}
	// Mode?
	if(SEqualNoCase(szCommand, "MODE"))
		{
		// Get all data
		StdStrBuf Channel = ircExtractPar(&szParameters);
		StdStrBuf Flags = ircExtractPar(&szParameters);
		StdStrBuf What = ircExtractPar(&szParameters);
		// Make sure it's a channel
		C4Network2IRCChannel *pChan = getChannel(Channel.getData());
		if(pChan)
			// Ask for names, because user prefixes might be out of sync
			Send("NAMES", Channel.getData());
		// Show Message
		PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_SETSMODE"), SenderNick.getData(), Flags.getData(), What.getData()).getData());
		}
	// Error?
	if(SEqualNoCase(szCommand, "ERROR"))
		{
		// Get message
		StdStrBuf Message = ircExtractPar(&szParameters);
		// Push it
		PushMessage(MSG_Server, szSender, Nick.getData(), Message.getData());
		}
	// Nickchange?
	if(SEqualNoCase(szCommand, "NICK"))
		{
		// Get new nick
		StdStrBuf NewNick = ircExtractPar(&szParameters);
		// Format status message
    StdStrBuf Message = FormatString(LoadResStr("IDS_MSG_ISNOWKNOWNAS"), SenderNick.getData(), NewNick.getData());
    // Rename on all channels
    for(C4Network2IRCChannel *pChan = pChannels; pChan; pChan = pChan->Next)
      if(pChan->getUser(SenderNick.getData()))
        {
        pChan->OnPart(SenderNick.getData(), "Nickchange");
        pChan->OnJoin(NewNick.getData());
        PushMessage(MSG_Status, szSender, pChan->getName(), Message.getData());
        }
    // Self?
    if(SenderNick == Nick)
      Nick = NewNick;
		}
	}
void C4Application::ParseCommandLine(int argc, char * argv[])
{

	StdStrBuf CmdLine("Command line:");
	for(int i = 0; i < argc; ++i) {
		CmdLine.Append(" ");
		CmdLine.Append(argv[i]);
	}
	Log(CmdLine.getData());

	ClearCommandLine();
	Game.NetworkActive = false;
	isEditor = 2;
	int c;
	while (1)
	{

		static struct option long_options[] =
		{
			// option, w/ argument?, set directly, set to...
			{"editor", no_argument, &isEditor, 1},
			{"fullscreen", no_argument, &isEditor, 0},
			{"debugwait", no_argument, &Game.DebugWait, 1},
			{"update", no_argument, &CheckForUpdates, 1},
			{"noruntimejoin", no_argument, &Config.Network.NoRuntimeJoin, 1},
			{"runtimejoin", no_argument, &Config.Network.NoRuntimeJoin, 0},
			{"noleague", no_argument, &Config.Network.LeagueServerSignUp, 0},
			{"league", no_argument, &Config.Network.LeagueServerSignUp, 1},
			{"nosignup", no_argument, &Config.Network.MasterServerSignUp, 0},
			{"signup", no_argument, &Config.Network.MasterServerSignUp, 1},
			
			{"debugrecread", required_argument, 0, 'K'},
			{"debugrecwrite", required_argument, 0, 'w'},

			{"client", required_argument, 0, 'c'},
			{"host", no_argument, 0, 'h'},
			{"debughost", required_argument, 0, 'H'},
			{"debugpass", required_argument, 0, 'P'},
			{"debug", required_argument, 0, 'D'},
			{"data", required_argument, 0, 'd'},
			{"startup", required_argument, 0, 's'},
			{"stream", required_argument, 0, 'e'},
			{"recdump", required_argument, 0, 'R'},
			{"comment", required_argument, 0, 'm'},
			{"pass", required_argument, 0, 'p'},
			{"udpport", required_argument, 0, 'u'},
			{"tcpport", required_argument, 0, 't'},
			{"join", required_argument, 0, 'j'},
			{"language", required_argument, 0, 'L'},
			{"scenpar", required_argument, 0, 'S'},

			{"observe", no_argument, 0, 'o'},
			{"nonetwork", no_argument, 0, 'N'},
			{"network", no_argument, 0, 'n'},
			{"record", no_argument, 0, 'r'},

			{"lobby", required_argument, 0, 'l'},

			{"debug-opengl", no_argument, &Config.Graphics.DebugOpenGL, 1},
			{0, 0, 0, 0}
		};
		int option_index = 0;
		c = getopt_long (argc, argv, "abc:d:f:",
			long_options, &option_index);
     		// no more options
		if (c == -1)
			break;
		switch (c)
		{
		case 0:
			// Signup
			if (SEqualNoCase(long_options[option_index].name, "signup"))
			{
				Game.NetworkActive = true;
			}
			// League
			if (SEqualNoCase(long_options[option_index].name, "league"))
			{
				Game.NetworkActive = true;
				Config.Network.MasterServerSignUp = true;
			}
			break;
		// Lobby
		case 'l':
			Game.fLobby = true;
			// lobby timeout specified? (e.g. --lobby=120)
			if (optarg)
			{
				Game.iLobbyTimeout = atoi(optarg);
				if (Game.iLobbyTimeout < 0) Game.iLobbyTimeout = 0;
			}
			break;
		case 'o': Game.fObserve = true; break;
		// Direct join
		case 'j':
			Game.NetworkActive = true;
			SCopy(optarg, Game.DirectJoinAddress, _MAX_PATH);
			break;
		case 'K':
			if (optarg && optarg[0])
			{
				LogF("Reading from DebugRec file '%s'", optarg);
				SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH);
			}
			else
				Log("Reading DebugRec from CtrlRec file in scenario record");
			Config.General.DebugRec = 1;
			Config.General.DebugRecWrite = 0;
			break;
		case 'w':
			if (optarg && optarg[0])
			{
				LogF("Writing to DebugRec file '%s'", optarg);
				SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH);
			}
			else
				Log("Writing DebugRec to CtrlRec file in scenario record");
			Config.General.DebugRec = 1;
			Config.General.DebugRecWrite = 1;
			break;
		case 'r': Game.Record = true; break;
		case 'n': Game.NetworkActive = true; break;
		case 'N': Game.NetworkActive = false; break;
		// Language override by parameter
		case 'L': SCopy(optarg, Config.General.LanguageEx, CFG_MaxString);
		// port overrides
		case 't': Config.Network.PortTCP = atoi(optarg); break;
		case 'u': Config.Network.PortUDP = atoi(optarg); break;
		// network game password
		case 'p': Network.SetPassword(optarg); break;
		// network game comment
		case 'm': Config.Network.Comment.CopyValidated(optarg); break;
		// record dump
		case 'R': Game.RecordDumpFile.Copy(optarg); break;
		// record stream
		case 'e': Game.RecordStream.Copy(optarg); break;
		// startup start screen
		case 's': C4Startup::SetStartScreen(optarg); break;
		// additional read-only data path
		case 'd': Reloc.AddPath(optarg); break;
		// debug options
		case 'D': Game.DebugPort = atoi(optarg); break;
		case 'P': Game.DebugPassword = optarg; break;
		case 'H': Game.DebugHost = optarg; break;
		// set custom scenario parameter by command line
		case 'S':
			{
			StdStrBuf sopt, soptval; sopt.Copy(optarg);
			int32_t val=1;
			if (sopt.SplitAtChar('=', &soptval)) val=atoi(soptval.getData());
			Game.StartupScenarioParameters.SetValue(sopt.getData(), val, false);
			}
			break;
		// debug configs
		case 'h':
			Game.NetworkActive = true;
			Game.fLobby = true;
			Config.Network.PortTCP = 11112;
			Config.Network.PortUDP = 11113;
			Config.Network.MasterServerSignUp = Config.Network.LeagueServerSignUp = false;
			break;
		case 'c':
			Game.NetworkActive = true;
			SCopy("localhost", Game.DirectJoinAddress, _MAX_PATH);
			Game.fLobby = true;
			Config.Network.PortTCP = 11112 + 2*(atoi(optarg)+1);
			Config.Network.PortUDP = 11113 + 2*(atoi(optarg)+1);
			break;
		case '?': /* getopt_long already printed an error message. */ break;
		default: assert(!"unexpected getopt_long return value");
		}
	}
	if (!Config.Network.MasterServerSignUp)
		Config.Network.LeagueServerSignUp = false;
	if (Game.fObserve || Game.fLobby)
		Game.NetworkActive = true;

	while (optind < argc)
	{
		char * szParameter = argv[optind++];
		{ // Strip trailing / that result from tab-completing unpacked c4groups
			int iLen = SLen(szParameter);
			if (iLen > 5 && szParameter[iLen-1] == '/' && szParameter[iLen-5] == '.' && szParameter[iLen-4] == 'o' && szParameter[iLen-3] == 'c')
			{
				szParameter[iLen-1] = '\0';
			}
		}
		// Scenario file
		if (SEqualNoCase(GetExtension(szParameter),"ocs"))
		{
			if(IsGlobalPath(szParameter))
				Game.SetScenarioFilename(szParameter);
			else
				Game.SetScenarioFilename((std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());

			continue;
		}
		if (SEqualNoCase(GetFilename(szParameter),"scenario.txt"))
		{
			Game.SetScenarioFilename(szParameter);
			continue;
		}
		// Player file
		if (SEqualNoCase(GetExtension(szParameter),"ocp"))
		{
			if(IsGlobalPath(szParameter))
				SAddModule(Game.PlayerFilenames, szParameter);
			else
				SAddModule(Game.PlayerFilenames, (std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());

			continue;
		}
		// Definition file
		if (SEqualNoCase(GetExtension(szParameter),"ocd"))
		{
			SAddModule(Game.DefinitionFilenames,szParameter);
			continue;
		}
		// Key file
		if (SEqualNoCase(GetExtension(szParameter),"c4k"))
		{
			Application.IncomingKeyfile.Copy(szParameter);
			continue;
		}
		// Update file
		if (SEqualNoCase(GetExtension(szParameter),"ocu"))
		{
			Application.IncomingUpdate.Copy(szParameter);
			continue;
		}
		// record stream
		if (SEqualNoCase(GetExtension(szParameter),"c4r"))
		{
			Game.RecordStream.Copy(szParameter);
		}
		// Direct join by URL
		if (SEqual2NoCase(szParameter, "clonk:"))
		{
			// Store address
			SCopy(szParameter + 6, Game.DirectJoinAddress, _MAX_PATH);
			SClearFrontBack(Game.DirectJoinAddress, '/');
			// Special case: if the target address is "update" then this is used for update initiation by url
			if (SEqualNoCase(Game.DirectJoinAddress, "update"))
			{
				Application.CheckForUpdates = true;
				Game.DirectJoinAddress[0] = 0;
				continue;
			}
			// Self-enable network
			Game.NetworkActive = true;
			continue;
		}
	}

#ifdef _WIN32
	// Clean up some forward/backward slach confusion since many internal OC file functions cannot handle both
	SReplaceChar(Game.ScenarioFilename, AltDirectorySeparator, DirectorySeparator);
	SReplaceChar(Game.PlayerFilenames, AltDirectorySeparator, DirectorySeparator);
	SReplaceChar(Game.DefinitionFilenames, AltDirectorySeparator, DirectorySeparator);
	Application.IncomingKeyfile.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
	Application.IncomingUpdate.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
	Game.RecordStream.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
#endif

	// Default to editor if scenario given, player mode otherwise
	if (isEditor == 2)
		isEditor = !!*Game.ScenarioFilename && !Config.General.OpenScenarioInGameMode;

	// record?
	Game.Record = Game.Record || (Config.Network.LeagueServerSignUp && Game.NetworkActive);

	// startup dialog required?
	QuitAfterGame = !isEditor && Game.HasScenario();
}
Example #29
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
		C4Markup 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';

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

		// Save into record log file, if available
		if(Control.GetRecord())
		{
			Control.GetRecord()->GetLogFile()->Write(TimeMessage.getData(), TimeMessage.getLength());
			#ifdef IMMEDIATEREC
				Control.GetRecord()->GetLogFile()->Flush();
			#endif
		}


		// Write to console
		if (fConsole)
		{
#if defined(_WIN32)
			// debug: output to VC console
			OutputDebugString(TimeMessage.GetWideChar());
#endif
#if !defined(_WIN32) || defined(USE_CONSOLE)
			fputs(TimeMessage.getData(),stdout);
			fflush(stdout);
#endif
		}

	}
	while (*pSrc);

	return true;
}
Example #30
0
C4Group *C4GroupSet::RegisterParentFolders(const char *szScenFilename)
{
	// the scenario filename may be a scenario or directly a group folder
	C4Group *pParentGroup=nullptr; bool fParentC4F;
	char szParentfolder[_MAX_PATH+1];
	if (SEqualNoCase(GetExtension(szScenFilename), "ocf"))
	{
		fParentC4F = true;
		SCopy(szScenFilename, szParentfolder, _MAX_PATH);
	}
	else
	{
		GetParentPath(szScenFilename,szParentfolder);
		fParentC4F = SEqualNoCase(GetExtension(szParentfolder), "ocf");
	}
	if (fParentC4F)
	{
		// replace all (back)slashes with zero-fields
		int32_t iOriginalLen=SLen(szParentfolder);
		for (int32_t i=0; i<iOriginalLen; ++i) if (szParentfolder[i]==DirectorySeparator || szParentfolder[i]=='/') szParentfolder[i]=0;
		// trace back until the file extension is no more .ocf
		int32_t iPos=iOriginalLen-1;
		while (iPos)
		{
			// ignore additional zero fields (double-backslashes)
			while (iPos && !szParentfolder[iPos]) --iPos;
			// break if end has been reached
			if (!iPos) break;
			// trace back until next zero field
			while (iPos && szParentfolder[iPos]) --iPos;
			// check extension of this folder
			if (!SEqualNoCase(GetExtension(szParentfolder+iPos+1), "ocf", 3)) break;
			// continue
		}
		// trace backwards, putting the (back)slashes in place again
		if (iPos)
		{
			szParentfolder[iPos+1+SLen(szParentfolder+iPos+1)]=szParentfolder[iPos]=DirectorySeparator;
			while (iPos--) if (!szParentfolder[iPos]) szParentfolder[iPos]=DirectorySeparator;
			++iPos;
		}
		// trace forward again, opening all folders (iPos is 0 again)
		int32_t iGroupIndex=0;
		while (iPos<iOriginalLen)
		{
			// ignore additional zero-fields
			while (iPos<iOriginalLen && !szParentfolder[iPos]) ++iPos;
			// break if end has been reached
			if (iPos>=iOriginalLen) break;
			// open this folder
			C4Group *pGroup = new C4Group();
			if (pParentGroup)
			{
				if (!pGroup->OpenAsChild(pParentGroup, szParentfolder+iPos))
				{
					LogFatal(FormatString("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), szParentfolder+iPos).getData());
					delete pGroup; return nullptr;
				}
			}
			else if (!Reloc.Open(*pGroup, szParentfolder+iPos))
			{
				LogFatal(FormatString("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), szParentfolder+iPos).getData());
				delete pGroup; return nullptr;
			}
			// set this group as new parent
			pParentGroup=pGroup;
			// add to group set, if this is a true scenario folder
			int32_t iContentsMask;
			if (WildcardMatch(C4CFN_FolderFiles, pParentGroup->GetName()))
				iContentsMask = C4GSCnt_Folder;
			else
				iContentsMask = C4GSCnt_Directory;
			if (!RegisterGroup(*pParentGroup, true, C4GSPrio_Folder+iGroupIndex++, iContentsMask))
				{ delete pParentGroup; LogFatal ("RegGrp: internal error"); return nullptr; }
			// advance by file name length
			iPos+=SLen(szParentfolder+iPos);
		}
	}
	return pParentGroup;
}