示例#1
0
void C4ValueMapData::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
{
	bool deserializing = pComp->isDeserializer();
	C4ValueMapNames *pOldNames = pNames;
	if (deserializing) Reset();
	// Compile item count
	int32_t iValueCnt;
	if (!deserializing) iValueCnt = pNames ? pNames->iSize : 0;
	pComp->Value(mkDefaultAdapt(iValueCnt, 0));
	// nuthing 2do for no items
	if (!iValueCnt) return;
	// Separator (';')
	pComp->Separator(StdCompiler::SEP_SEP2);
	// Data
	char **ppNames = !deserializing ? pNames->pNames : new char * [iValueCnt];
	if (deserializing) for (int32_t i = 0; i < iValueCnt; i++) ppNames[i] = nullptr;
	C4Value *pValues = !deserializing ? pData : new C4Value [iValueCnt];
	// Compile
	try
	{
		for (int32_t i = 0; i < iValueCnt; i++)
		{
			// Separate
			if (i) pComp->Separator();
			// Name
			StdStrBuf Name;
			if (!deserializing) Name.Ref(ppNames[i]);
			pComp->Value(mkParAdapt(Name, StdCompiler::RCT_Idtf));
			if (deserializing) ppNames[i] = Name.GrabPointer();
			// Separator ('=')
			pComp->Separator(StdCompiler::SEP_SET);
			// Value
			pComp->Value(mkParAdapt(pValues[i], numbers));
		}
	}
	catch (...)
	{
		// make sure no mem is leaked on compiler error in name list
		if (deserializing)
		{
			for (int32_t i = 0; i < iValueCnt; i++) if (ppNames[i]) free(ppNames[i]);
			delete [] ppNames;
			delete [] pValues;
		}
		throw;
	}
	// Set
	if (deserializing)
	{
		// Set
		CreateTempNameList();
		pNames->SetNameArray(const_cast<const char **>(ppNames), iValueCnt);
		for (int32_t i = 0; i < iValueCnt; i++) free(ppNames[i]);
		delete [] ppNames; delete [] pData;
		pData = pValues;
		// Assign old name list
		if (pOldNames) SetNameList(pOldNames);
	}
}
bool C4InteractiveThread::ThreadLogDebug(const char *szMessage, ...)
{
	// format message
	va_list lst; va_start(lst, szMessage);
	StdStrBuf Msg = FormatStringV(szMessage, lst);
	// send to main thread
	return PushEvent(Ev_LogDebug, Msg.GrabPointer());
}
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;
}
示例#4
0
BOOL C4Scenario::Decompile(char **ppOutput, int32_t *ipSize, bool fSaveSection)
	{
  try
    {
    // Decompile
    StdStrBuf Buf = DecompileToBuf<StdCompilerINIWrite>(mkParAdapt(*this, fSaveSection));
    // Return
    *ppOutput = Buf.GrabPointer();
    *ipSize = Buf.getSize();
    }
  catch(StdCompiler::Exception *)
    { return FALSE; }
  return TRUE;
	}
bool C4ObjectInfoCore::Decompile(char **ppOutput, size_t *ipSize)
{
	StdStrBuf Buf;
	if (!DecompileToBuf_Log<StdCompilerINIWrite>(
	      mkNamingAdapt(*this, "ObjectInfo"),
	      &Buf,
	      "ObjectInfo"))
	{
		if (ppOutput) *ppOutput = NULL;
		if (ipSize) *ipSize = 0;
		return false;
	}
	if (ppOutput) *ppOutput = Buf.GrabPointer();
	if (ipSize) *ipSize = Buf.getSize();
	return true;
}
示例#6
0
C4FileSelDlg::DefaultListItem::DefaultListItem(const char *szFilename,
                                               bool fTruncateExtension,
                                               bool fCheckbox, bool fGrayed,
                                               C4GUI::Icons eIcon)
    : C4FileSelDlg::ListItem(szFilename),
      pLbl(NULL),
      pCheck(NULL),
      pKeyCheck(NULL),
      fGrayed(fGrayed) {
  StdStrBuf sLabel;
  if (szFilename)
    sLabel.Ref(::GetFilename(szFilename));
  else
    sLabel.Ref(LoadResStr("IDS_CTL_NONE"));
  if (szFilename && fTruncateExtension) {
    sLabel.Copy();
    char *szFilename = sLabel.GrabPointer();
    RemoveExtension(szFilename);
    sLabel.Take(szFilename);
  }
  rcBounds.Hgt = C4GUI::GetRes()->TextFont.GetLineHeight();
  UpdateSize();
  C4GUI::ComponentAligner caMain(GetContainedClientRect(), 0, 0);
  int32_t iHeight = caMain.GetInnerHeight();
  if (fCheckbox) {
    pCheck = new C4GUI::CheckBox(caMain.GetFromLeft(iHeight), NULL, false);
    if (fGrayed) pCheck->SetEnabled(false);
    AddElement(pCheck);
    pKeyCheck = new C4KeyBinding(
        C4KeyCodeEx(K_SPACE), "FileSelToggleFileActive", KEYSCOPE_Gui,
        new C4GUI::ControlKeyCB<ListItem>(*this, &ListItem::UserToggleCheck),
        C4CustomKey::PRIO_Ctrl);
  }
  C4GUI::Icon *pIco = new C4GUI::Icon(caMain.GetFromLeft(iHeight), eIcon);
  AddElement(pIco);
  pLbl = new C4GUI::Label(
      sLabel.getData(), caMain.GetAll(), ALeft,
      fGrayed ? C4GUI_CheckboxDisabledFontClr : C4GUI_CheckboxFontClr);
  AddElement(pLbl);
}
示例#7
0
bool C4Network2IO::HandlePacket(const C4NetIOPacket &rPacket, C4Network2IOConnection *pConn, bool fThread)
{
    // security: add connection reference
    if (!pConn) return false;
    pConn->AddRef();

    // accept only PID_Conn and PID_Ping on non-accepted connections
    if(!pConn->isHalfAccepted())
        if(rPacket.getStatus() != PID_Conn && rPacket.getStatus() != PID_Ping && rPacket.getStatus() != PID_ConnRe)
            return false;

    // unpack packet (yet another no-idea-why-it's-needed-cast)
    C4IDPacket Pkt;
    C4PacketBase &PktB = Pkt;
    try
    {
        PktB.unpack(rPacket);
    }
    catch (StdCompiler::Exception *pExc)
    {
        Application.InteractiveThread.ThreadLog("Network: error: Failed to unpack packet id %02x: %s", rPacket.getStatus(), pExc->Msg.getData());
        delete pExc;
#ifndef _DEBUG
        pConn->Close();
#endif
        return false;
    }

    // dump packet (network thread only)
#if(C4NET2IO_DUMP_LEVEL > 0)
    if (Config.Network.PacketLogging && fThread && Pkt.getPktType() != PID_Ping && Pkt.getPktType() != PID_Pong && Pkt.getPktType() != PID_NetResData)
    {
        // StdStrBuf PacketDump = DecompileToBuf<StdCompilerINIWrite>(mkNamingAdaptrPacket);
        StdStrBuf PacketHeader = FormatString("HandlePacket: %s by %s:%d (%lu bytes, counter %d)",
                                              C4TimeMilliseconds::Now().AsString().getData(),
                                              inet_ntoa(pConn->getPeerAddr().sin_addr), htons(pConn->getPeerAddr().sin_port),
                                              static_cast<unsigned long>(rPacket.getSize()), pConn->getInPacketCounter());
        StdStrBuf Dump = DecompileToBuf<StdCompilerINIWrite>(mkNamingAdapt(Pkt, PacketHeader.getData()));
        // Put it directly. The standard functions behind StdBuf.Format seem to choke when you pass them too much data.
        Application.InteractiveThread.PushEvent(Ev_LogSilent, Dump.GrabPointer());
    }
#endif

    // search packet handling data
    bool fSendToMainThread = false, fHandled = false;
    for (const C4PktHandlingData *pHData = PktHandlingData; pHData->ID != PID_None; pHData++)
        if (pHData->ID == rPacket.getStatus())
        {
            // correct thread?
            if (!pHData->ProcByThread == !fThread)
            {
                // connection accepted?
                if (pHData->AcceptedOnly || pConn->isAccepted() || pConn->isClosed())
                {
                    fHandled = true;
#if(C4NET2IO_DUMP_LEVEL > 2)
                    C4TimeMilliseconds tStart = C4TimeMilliseconds::Now();
#endif

                    // call handler(s)
                    CallHandlers(pHData->HandlerID, &Pkt, pConn, fThread);

#if(C4NET2IO_DUMP_LEVEL > 2)
                    uint32_t iBlockedTime = C4TimeMilliseconds::Now() - tStart;
                    if (fThread && iBlockedTime > 100)
                    {
                        Application.InteractiveThread.ThreadLogS("HandlePacket: ... blocked for %u ms!", iBlockedTime);
                    }
#endif

                }
            }
            // transfer to main thread?
            else if (!pHData->ProcByThread && fThread)
            {
                fHandled = true;
                fSendToMainThread = true;
            }
        }

    // send to main thread?
    if (fSendToMainThread)
    {
        // create data
        NetEvPacketData *pEvData = new NetEvPacketData;
        pEvData->Packet.Take(rPacket.Duplicate());
        pEvData->Conn = pConn;
        pConn->AddRef();
        // trigger event
        if (!Application.InteractiveThread.PushEvent(Ev_Net_Packet, pEvData))
            Application.InteractiveThread.ThreadLogS("...push event ");
    }

    // unhandled?
    if (!fHandled && !pConn->isClosed())
        Application.InteractiveThread.ThreadLog("Network: Unhandled packet (status %02x)", rPacket.getStatus());

    // remove connection reference
    pConn->DelRef();
    return fHandled;
}