OpenClonk
C4Network2Res Class Reference

#include <C4Network2Res.h>

Collaboration diagram for C4Network2Res:
[legend]

Classes

struct  ClientChunks
 
class  Ref
 

Public Member Functions

 C4Network2Res (C4Network2ResList *pnParent)
 
 ~C4Network2Res ()
 
C4Network2ResType getType () const
 
const C4Network2ResCoregetCore () const
 
bool isDirty () const
 
bool isAnonymous () const
 
int32_t getResID () const
 
int32_t getResClient () const
 
const char * getFile () const
 
CStdCSecgetFileCSec ()
 
int32_t getLastReqTime () const
 
bool isRemoved () const
 
bool isLoading () const
 
bool isComplete () const
 
int32_t getPresentPercent () const
 
bool isTempFile () const
 
bool SetByFile (const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
 
bool SetByGroup (C4Group *pGrp, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
 
bool SetByCore (const C4Network2ResCore &nCore, bool fSilent=false, const char *szAsFilename=nullptr, int32_t iRecursion=0)
 
bool SetLoad (const C4Network2ResCore &nCore)
 
bool SetDerived (const char *strName, const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iDResID)
 
void ChangeID (int32_t inID)
 
bool IsBinaryCompatible ()
 
bool GetStandalone (char *pTo, int32_t iMaxL, bool fSetOfficial, bool fAllowUnloadable=false, bool fSilent=false)
 
bool CalculateSHA ()
 
bool SaveBackFile ()
 
C4Network2Res::Ref Derive ()
 
bool FinishDerive ()
 
bool FinishDerive (const C4Network2ResCore &nCore)
 
bool SendStatus (C4Network2IOConnection *pTo=nullptr)
 
bool SendChunk (uint32_t iChunk, int32_t iToClient)
 
void AddRef ()
 
void DelRef ()
 
void OnDiscover (C4Network2IOConnection *pBy)
 
void OnStatus (const C4Network2ResChunkData &rChunkData, C4Network2IOConnection *pBy)
 
void OnChunk (const C4Network2ResChunk &rChunk)
 
bool DoLoad ()
 
bool NeedsDiscover ()
 
C4GroupOpenAsGrp () const
 
void Remove ()
 
void Clear ()
 

Protected Member Functions

int32_t OpenFileRead ()
 
int32_t OpenFileWrite ()
 
void StartNewLoads ()
 
bool StartLoad (int32_t iFromClient, const C4Network2ResChunkData &Chunks)
 
void EndLoad ()
 
void ClearLoad ()
 
void RemoveLoad (C4Network2ResLoad *pLoad)
 
void RemoveCChunks (ClientChunks *pChunks)
 
bool OptimizeStandalone (bool fSilent)
 

Protected Attributes

C4Network2ResCore Core
 
C4Network2ResChunkData Chunks
 
bool fDirty
 
CStdCSec FileCSec
 
char szFile [_MAX_PATH_LEN]
 
char szStandalone [_MAX_PATH_LEN]
 
bool fTempFile
 
bool fStandaloneFailed
 
std::atomic_long iRefCnt
 
bool fRemoved
 
int32_t iLastReqTime
 
bool fLoading
 
struct C4Network2Res::ClientChunkspCChunks
 
time_t iDiscoverStartTime
 
C4Network2ResLoadpLoads
 
int32_t iLoadCnt
 
C4Network2RespNext
 
C4Network2ResListpParent
 

Friends

class C4Network2ResList
 
class C4Network2ResChunk
 

Detailed Description

Definition at line 178 of file C4Network2Res.h.


Class Documentation

◆ C4Network2Res::ClientChunks

struct C4Network2Res::ClientChunks

Definition at line 227 of file C4Network2Res.h.

Collaboration diagram for C4Network2Res::ClientChunks:
[legend]
Class Members
C4Network2ResChunkData Chunks
int32_t ClientID
ClientChunks * Next

Constructor & Destructor Documentation

◆ C4Network2Res()

C4Network2Res::C4Network2Res ( C4Network2ResList pnParent)

Definition at line 338 of file C4Network2Res.cpp.

339  : fDirty(false),
340  fTempFile(false), fStandaloneFailed(false),
341  iRefCnt(0), fRemoved(false),
342  iLastReqTime(0),
343  fLoading(false),
344  pCChunks(nullptr), iDiscoverStartTime(0), pLoads(nullptr), iLoadCnt(0),
345  pNext(nullptr),
346  pParent(pnParent)
347 {
348  szFile[0] = szStandalone[0] = '\0';
349 }
int32_t iLoadCnt
std::atomic_long iRefCnt
time_t iDiscoverStartTime
C4Network2ResList * pParent
bool fStandaloneFailed
C4Network2Res * pNext
char szFile[_MAX_PATH_LEN]
int32_t iLastReqTime
char szStandalone[_MAX_PATH_LEN]
struct C4Network2Res::ClientChunks * pCChunks
C4Network2ResLoad * pLoads

References szFile, and szStandalone.

Referenced by Derive().

Here is the caller graph for this function:

◆ ~C4Network2Res()

C4Network2Res::~C4Network2Res ( )

Definition at line 351 of file C4Network2Res.cpp.

352 {
353  assert(!pNext);
354  Clear();
355 }

References Clear(), and pNext.

Here is the call graph for this function:

Member Function Documentation

◆ AddRef()

void C4Network2Res::AddRef ( )

Definition at line 832 of file C4Network2Res.cpp.

833 {
834  ++iRefCnt;
835 }

References iRefCnt.

Referenced by C4Network2ResList::Add(), C4Network2Res::Ref::Ref(), and C4Network2Res::Ref::Set().

Here is the caller graph for this function:

◆ CalculateSHA()

bool C4Network2Res::CalculateSHA ( )

Definition at line 657 of file C4Network2Res.cpp.

658 {
659  // already present?
660  if (Core.hasFileSHA()) return true;
661  // get the file
663  if (!GetStandalone(szStandalone, _MAX_PATH, false))
665  // get the hash
666  BYTE hash[SHA_DIGEST_LENGTH];
667  if (!GetFileSHA1(szStandalone, hash))
668  return false;
669  // save it back
670  Core.SetFileSHA(hash);
671  // okay
672  return true;
673 }
bool GetFileSHA1(const char *szFilename, BYTE *pSHA1)
Definition: CStdFile.cpp:381
#define _MAX_PATH
#define _MAX_PATH_LEN
uint8_t BYTE
#define SHA_DIGEST_LENGTH
Definition: SHA1.h:42
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
void SetFileSHA(BYTE *pSHA)
bool hasFileSHA() const
Definition: C4Network2Res.h:92
bool GetStandalone(char *pTo, int32_t iMaxL, bool fSetOfficial, bool fAllowUnloadable=false, bool fSilent=false)
C4Network2ResCore Core

References _MAX_PATH, _MAX_PATH_LEN, Core, GetFileSHA1(), GetStandalone(), C4Network2ResCore::hasFileSHA(), SCopy(), C4Network2ResCore::SetFileSHA(), SHA_DIGEST_LENGTH, szFile, and szStandalone.

Referenced by C4GameRes::CalcHash().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ChangeID()

void C4Network2Res::ChangeID ( int32_t  inID)

Definition at line 529 of file C4Network2Res.cpp.

530 {
531  Core.SetID(inID);
532 }
void SetID(int32_t inID)
Definition: C4Network2Res.h:99

References Core, and C4Network2ResCore::SetID().

Here is the call graph for this function:

◆ Clear()

void C4Network2Res::Clear ( )

Definition at line 956 of file C4Network2Res.cpp.

957 {
958  CStdLock FileLock(&FileCSec);
959  // delete files
960  if (fTempFile)
961  if (FileExists(szFile))
962  if (!EraseFile(szFile))
963  LogSilentF("Network: Could not delete temporary resource file (%s)", strerror(errno));
964  if (szStandalone[0] && !SEqual(szFile, szStandalone))
966  if (!EraseFile(szStandalone))
967  LogSilentF("Network: Could not delete temporary resource file (%s)", strerror(errno));
968  szFile[0] = szStandalone[0] = '\0';
969  fDirty = false;
970  fTempFile = false;
971  Core.Clear();
972  Chunks.Clear();
973  fRemoved = false;
974  ClearLoad();
975 }
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:272
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
bool FileExists(const char *szFileName)
bool EraseFile(const char *szFileName)
CStdCSec FileCSec
C4Network2ResChunkData Chunks

References Chunks, C4Network2ResCore::Clear(), C4Network2ResChunkData::Clear(), ClearLoad(), Core, EraseFile(), fDirty, FileCSec, FileExists(), fRemoved, fTempFile, LogSilentF(), SEqual(), szFile, and szStandalone.

Referenced by SetByGroup(), SetDerived(), SetLoad(), and ~C4Network2Res().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearLoad()

void C4Network2Res::ClearLoad ( )
protected

Definition at line 1097 of file C4Network2Res.cpp.

1098 {
1099  // remove client chunks and loads
1100  fLoading = false;
1101  while (pCChunks) RemoveCChunks(pCChunks);
1102  while (pLoads) RemoveLoad(pLoads);
1104 }
void RemoveCChunks(ClientChunks *pChunks)
void RemoveLoad(C4Network2ResLoad *pLoad)

References fLoading, iDiscoverStartTime, iLoadCnt, pCChunks, pLoads, RemoveCChunks(), and RemoveLoad().

Referenced by Clear(), and EndLoad().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DelRef()

void C4Network2Res::DelRef ( )

Definition at line 837 of file C4Network2Res.cpp.

838 {
839  if (--iRefCnt == 0)
840  delete this;
841 }

References iRefCnt.

Referenced by C4Network2Res::Ref::Clear().

Here is the caller graph for this function:

◆ Derive()

C4Network2Res::Ref C4Network2Res::Derive ( )

Definition at line 676 of file C4Network2Res.cpp.

677 {
678  // Called before the file is changed. Rescues all files and creates a
679  // new resource for the file. This resource is flagged as "anonymous", as it
680  // has no official core (no res ID, to be exact).
681  // The resource gets its final core when FinishDerive() is called.
682 
683  // For security: This doesn't make much sense if the resource is currently being
684  // loaded. So better assume the caller doesn't know what he's doing and check.
685  if (isLoading()) return nullptr;
686 
687  CStdLock FileLock(&FileCSec);
688  // Save back original file name
689  char szOrgFile[_MAX_PATH_LEN];
690  SCopy(szFile, szOrgFile, _MAX_PATH);
691  bool fOrgTempFile = fTempFile;
692 
693  // Create a copy of the file, if neccessary
695  {
696  if (!pParent->FindTempResFileName(szOrgFile, szFile))
697  { Log("Derive: could not find free name for temporary file!"); return nullptr; }
698  if (!C4Group_CopyItem(szOrgFile, szFile))
699  { Log("Derive: could not copy to temporary file!"); return nullptr; }
700  // set standalone
701  if (*szStandalone)
703  fTempFile = true;
704  }
705  else
706  {
707  // Standlone exists: Just set szFile to point on the standlone. It's
708  // assumed that the original file isn't of intrest after this point anyway.
710  fTempFile = true;
711  }
712 
713  Application.InteractiveThread.ThreadLogS("Network: Resource: deriving from %d:%s, original at %s", getResID(), Core.getFileName(), szFile);
714 
715  // (note: should remove temp file if something fails after this point)
716 
717  // create new resource
719  if (!pDRes) return nullptr;
720 
721  // initialize
722  if (!pDRes->SetDerived(Core.getFileName(), szOrgFile, fOrgTempFile, getType(), getResID()))
723  return nullptr;
724 
725  // add to list
726  pParent->Add(pDRes);
727 
728  // return new resource
729  return pDRes;
730 }
C4Application Application
Definition: C4Globals.cpp:44
bool C4Group_CopyItem(const char *source, const char *target, bool no_sorting, bool reset_attributes)
Definition: C4Group.cpp:115
bool Log(const char *szMessage)
Definition: C4Log.cpp:204
C4InteractiveThread InteractiveThread
Definition: C4Application.h:45
bool ThreadLogS(const char *szMessage,...) GNUC_FORMAT_ATTRIBUTE_O
const char * getFileName() const
Definition: C4Network2Res.h:94
C4Network2Res(C4Network2ResList *pnParent)
int32_t getResID() const
C4Network2ResType getType() const
bool isLoading() const
bool SetDerived(const char *strName, const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iDResID)
bool FindTempResFileName(const char *szFilename, char *pTarget)
void Add(C4Network2Res *pRes)

References _MAX_PATH, _MAX_PATH_LEN, C4Network2ResList::Add(), Application, C4Group_CopyItem(), C4Network2Res(), Core, FileCSec, C4Network2ResList::FindTempResFileName(), fTempFile, C4Network2ResCore::getFileName(), getResID(), getType(), C4Application::InteractiveThread, isLoading(), Log(), pParent, SCopy(), SEqual(), SetDerived(), szFile, szStandalone, and C4InteractiveThread::ThreadLogS().

Referenced by C4Player::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoLoad()

bool C4Network2Res::DoLoad ( )

Definition at line 911 of file C4Network2Res.cpp.

912 {
913  if (!fLoading) return true;
914  // any loads currently active?
915  if (iLoadCnt)
916  {
917  // check for load timeouts
918  int32_t iLoadsRemoved = 0;
919  for (C4Network2ResLoad *pLoad = pLoads, *pNext; pLoad; pLoad = pNext)
920  {
921  pNext = pLoad->Next();
922  if (pLoad->CheckTimeout())
923  {
924  RemoveLoad(pLoad);
925  iLoadsRemoved++;
926  }
927  }
928  // start new loads
929  if (iLoadsRemoved) StartNewLoads();
930  }
931  else
932  {
933  // discover timeout?
934  if (iDiscoverStartTime)
935  if (difftime(time(nullptr), iDiscoverStartTime) > C4NetResDiscoverTimeout)
936  return false;
937  }
938  // ok
939  return true;
940 }
const int32_t C4NetResDiscoverTimeout
Definition: C4Network2Res.h:30

References C4NetResDiscoverTimeout, fLoading, iDiscoverStartTime, iLoadCnt, pLoads, pNext, RemoveLoad(), and StartNewLoads().

Referenced by C4Network2ResList::OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EndLoad()

void C4Network2Res::EndLoad ( )
protected

Definition at line 1086 of file C4Network2Res.cpp.

1087 {
1088  // clear loading data
1089  ClearLoad();
1090  // set complete
1091  fLoading = false;
1092  // call handler
1093  assert(pParent);
1094  pParent->OnResComplete(this);
1095 }
void OnResComplete(C4Network2Res *pRes)

References ClearLoad(), fLoading, C4Network2ResList::OnResComplete(), and pParent.

Referenced by OnChunk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FinishDerive() [1/2]

bool C4Network2Res::FinishDerive ( )

Definition at line 732 of file C4Network2Res.cpp.

733 {
734  // All changes have been made. Register this resource with a new ID.
735 
736  // security
737  if (!isAnonymous()) return false;
738 
739  CStdLock FileLock(&FileCSec);
740  // Save back data
741  int32_t iDerID = Core.getDerID();
742  char szName[_MAX_PATH_LEN]; SCopy(Core.getFileName(), szName, _MAX_PATH);
743  char szFileC[_MAX_PATH_LEN]; SCopy(szFile, szFileC, _MAX_PATH);
744  // Set by file
745  if (!SetByFile(szFileC, fTempFile, getType(), pParent->nextResID(), szName))
746  return false;
747  // create standalone
748  if (!GetStandalone(nullptr, 0, true))
749  return false;
750  // Set ID
751  Core.SetDerived(iDerID);
752  // announce derive
754  // derivation is dirty bussines
755  fDirty = true;
756  // ok
757  return true;
758 }
C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr=C4NetIO::addr_t())
Definition: C4PacketBase.h:40
@ PID_NetResDerive
Definition: C4PacketBase.h:131
bool BroadcastMsg(const C4NetIOPacket &rPkt)
void SetDerived(int32_t inDerID)
int32_t getDerID() const
Definition: C4Network2Res.h:87
bool isAnonymous() const
bool SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
C4Network2IO * getIOClass()

References _MAX_PATH, _MAX_PATH_LEN, C4Network2IO::BroadcastMsg(), Core, fDirty, FileCSec, fTempFile, C4Network2ResCore::getDerID(), C4Network2ResCore::getFileName(), C4Network2ResList::getIOClass(), GetStandalone(), getType(), isAnonymous(), MkC4NetIOPacket(), C4Network2ResList::nextResID(), PID_NetResDerive, pParent, SCopy(), SetByFile(), C4Network2ResCore::SetDerived(), and szFile.

Here is the call graph for this function:

◆ FinishDerive() [2/2]

bool C4Network2Res::FinishDerive ( const C4Network2ResCore nCore)

Definition at line 760 of file C4Network2Res.cpp.

761 {
762  // security
763  if (!isAnonymous()) return false;
764  // Set core
765  Core = nCore;
766  // Set chunks (assume the resource is complete)
768 
769  // Note that the Contents-CRC is /not/ checked. Derivation needs to be
770  // synchronized outside of C4Network2Res.
771 
772  // But note that the resource /might/ be binary compatible (though very
773  // unlikely), so do not set fNotBinaryCompatible.
774 
775  // ok
776  return true;
777 }
void SetComplete(int32_t iChunkCnt)
uint32_t getChunkCnt() const
Definition: C4Network2Res.h:96

References Chunks, Core, C4Network2ResCore::getChunkCnt(), isAnonymous(), and C4Network2ResChunkData::SetComplete().

Here is the call graph for this function:

◆ getCore()

const C4Network2ResCore& C4Network2Res::getCore ( ) const
inline

Definition at line 239 of file C4Network2Res.h.

239 { return Core; }

References Core.

Referenced by C4Network2ResList::AddByCore(), C4Network2ResChunk::AddTo(), C4PlayerInfo::CompileFunc(), C4Network2::CreateDynamic(), C4PlayerInfo::LoadFromLocalFile(), C4Network2ResList::OnResComplete(), C4PlayerInfoList::RecreatePlayers(), C4Network2::RetrieveRes(), C4Network2ResChunk::Set(), and C4GameRes::SetNetRes().

Here is the caller graph for this function:

◆ getFile()

const char* C4Network2Res::getFile ( ) const
inline

Definition at line 244 of file C4Network2Res.h.

244 { return szFile; }

References szFile.

Referenced by C4PlayerInfo::GetLocalJoinFilename(), C4PlayerInfo::LoadBigIcon(), C4ControlJoinPlayer::PreRec(), C4MessageInput::ProcessCommand(), C4Network2::RetrieveScenario(), C4Network2ResChunk::Set(), and C4GameRes::SetNetRes().

Here is the caller graph for this function:

◆ getFileCSec()

CStdCSec* C4Network2Res::getFileCSec ( )
inline

Definition at line 245 of file C4Network2Res.h.

245 { return &FileCSec; }

References FileCSec.

◆ getLastReqTime()

int32_t C4Network2Res::getLastReqTime ( ) const
inline

Definition at line 246 of file C4Network2Res.h.

246 { return iLastReqTime; }

References iLastReqTime.

◆ getPresentPercent()

int32_t C4Network2Res::getPresentPercent ( ) const
inline

Definition at line 250 of file C4Network2Res.h.

250 { return fLoading ? Chunks.getPresentPercent() : 100; }
int32_t getPresentPercent() const

References Chunks, fLoading, and C4Network2ResChunkData::getPresentPercent().

Referenced by C4Network2::RetrieveRes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getResClient()

int32_t C4Network2Res::getResClient ( ) const
inline

Definition at line 243 of file C4Network2Res.h.

243 { return Core.getID() >> 16; }
int32_t getID() const
Definition: C4Network2Res.h:86

References Core, and C4Network2ResCore::getID().

Here is the call graph for this function:

◆ getResID()

int32_t C4Network2Res::getResID ( ) const
inline

Definition at line 242 of file C4Network2Res.h.

242 { return Core.getID(); }

References Core, and C4Network2ResCore::getID().

Referenced by C4Network2ResChunk::AddTo(), Derive(), C4ClientPlayerInfos::GetPlayerInfoByRes(), C4Network2ResList::getRefNextRes(), C4Network2Players::HandlePlayerInfoUpdRequest(), isAnonymous(), OnChunk(), C4Network2ResChunk::Set(), and C4Network2ResDlg::Update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetStandalone()

bool C4Network2Res::GetStandalone ( char *  pTo,
int32_t  iMaxL,
bool  fSetOfficial,
bool  fAllowUnloadable = false,
bool  fSilent = false 
)

Definition at line 551 of file C4Network2Res.cpp.

552 {
553  // already set?
554  if (szStandalone[0])
555  {
556  if (pTo) SCopy(szStandalone, pTo, iMaxL);
557  return true;
558  }
559  // already tried and failed? No point in retrying
560  if (fStandaloneFailed) return false;
561  // not loadable? Wo won't be able to check the standalone as the core will lack the needed information.
562  // the standalone won't be interesting in this case, anyway.
563  if (!fSetOfficial && !Core.isLoadable()) return false;
564  // set flag, so failure below will let future calls fail
565  fStandaloneFailed = true;
566  // lock file
567  CStdLock FileLock(&FileCSec);
568 
569  // directory?
570  SCopy(szFile, szStandalone, sizeof(szStandalone)-1);
571  if (DirectoryExists(szFile))
572  {
573  // size check for the directory, if allowed
574  if (fAllowUnloadable)
575  {
576  uint32_t iDirSize;
578  { if (!fSilent) LogF("Network: could not get directory size of %s!", szFile); szStandalone[0] = '\0'; return false; }
579  if (iDirSize > uint32_t(Config.Network.MaxLoadFileSize))
580  { if (!fSilent) LogSilentF("Network: %s over size limit, will be marked unloadable!", szFile); szStandalone[0] = '\0'; return false; }
581  }
582  // log - this may take a few seconds
583  if (!fSilent) LogF(LoadResStr("IDS_PRC_NETPACKING"), GetFilename(szFile));
584  // pack inplace?
585  if (!fTempFile)
586  {
588  { if (!fSilent) Log("GetStandalone: could not find free name for temporary file!"); szStandalone[0] = '\0'; return false; }
590  { if (!fSilent) Log("GetStandalone: could not pack directory!"); szStandalone[0] = '\0'; return false; }
591  }
593  { if (!fSilent) Log("GetStandalone: could not pack directory!"); if (!SEqual(szFile, szStandalone)) EraseDirectory(szStandalone); szStandalone[0] = '\0'; return false; }
594  // make sure directory is packed
596  { if (!fSilent) Log("GetStandalone: directory hasn't been packed!"); if (!SEqual(szFile, szStandalone)) EraseDirectory(szStandalone); szStandalone[0] = '\0'; return false; }
597  // fallthru
598  }
599 
600  // doesn't exist physically?
601  if (!FileExists(szStandalone))
602  {
603  // try C4Group (might be packed)
605  { if (!fSilent) Log("GetStandalone: could not find free name for temporary file!"); szStandalone[0] = '\0'; return false; }
607  { if (!fSilent) Log("GetStandalone: could not copy to temporary file!"); szStandalone[0] = '\0'; return false; }
608  }
609 
610  // remains missing? give up.
611  if (!FileExists(szStandalone))
612  { if (!fSilent) Log("GetStandalone: file not found!"); szStandalone[0] = '\0'; return false; }
613 
614  // do optimizations (delete unneeded entries)
615  if (!OptimizeStandalone(fSilent))
616  { if (!SEqual(szFile, szStandalone)) EraseItem(szStandalone); szStandalone[0] = '\0'; return false; }
617 
618  // get file size
619  size_t iSize = FileSize(szStandalone);
620  // size limit
621  if (fAllowUnloadable)
622  if (iSize > uint32_t(Config.Network.MaxLoadFileSize))
623  { if (!fSilent) LogSilentF("Network: %s over size limit, will be marked unloadable!", szFile); szStandalone[0] = '\0'; return false; }
624  // check
625  if (!fSetOfficial && iSize != Core.getFileSize())
626  {
627  // remove file
629  szStandalone[0] = '\0';
630  // sorry, this version isn't good enough :(
631  return false;
632  }
633 
634  // calc checksum
635  uint32_t iCRC32;
636  if (!GetFileCRC(szStandalone, &iCRC32))
637  { if (!fSilent) Log("GetStandalone: could not calculate checksum!"); return false; }
638  // set / check
639  if (!fSetOfficial && iCRC32 != Core.getFileCRC())
640  {
641  // remove file, return
643  szStandalone[0] = '\0';
644  return false;
645  }
646 
647  // we didn't fail
648  fStandaloneFailed = false;
649  // mark resource as loadable and safe file information
650  Core.SetLoadable(iSize, iCRC32);
651  // set up chunk data
653  // ok
654  return true;
655 }
C4Config Config
Definition: C4Config.cpp:930
bool C4Group_PackDirectoryTo(const char *filename, const char *to_filename)
Definition: C4Group.cpp:292
bool C4Group_PackDirectory(const char *filename)
Definition: C4Group.cpp:371
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
bool GetFileCRC(const char *szFilename, uint32_t *pCRC32)
Definition: CStdFile.cpp:355
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:833
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:708
bool EraseDirectory(const char *szDirName)
Definition: StdFile.cpp:785
char * GetFilename(char *szPath)
Definition: StdFile.cpp:42
size_t FileSize(const char *fname)
int iSize
Definition: TstC4NetIO.cpp:32
C4ConfigNetwork Network
Definition: C4Config.h:259
int32_t MaxLoadFileSize
Definition: C4Config.h:157
void SetLoadable(uint32_t iSize, uint32_t iCRC)
uint32_t getFileCRC() const
Definition: C4Network2Res.h:90
uint32_t getFileSize() const
Definition: C4Network2Res.h:89
bool isLoadable() const
Definition: C4Network2Res.h:88
bool OptimizeStandalone(bool fSilent)
static bool GetDirSize(const char *szPath, uint32_t *pSize, uint32_t inMaxSize=~0)

References C4Group_CopyItem(), C4Group_PackDirectory(), C4Group_PackDirectoryTo(), Chunks, Config, Core, DirectoryExists(), EraseDirectory(), EraseItem(), FileCSec, FileExists(), FileSize(), C4Network2ResList::FindTempResFileName(), fStandaloneFailed, fTempFile, C4Network2ResCore::getChunkCnt(), DirSizeHelper::GetDirSize(), C4Network2ResCore::getFileCRC(), GetFileCRC(), GetFilename(), C4Network2ResCore::getFileSize(), iSize, C4Network2ResCore::isLoadable(), LoadResStr(), Log(), LogF(), LogSilentF(), C4ConfigNetwork::MaxLoadFileSize, C4Config::Network, OptimizeStandalone(), pParent, SCopy(), SEqual(), C4Network2ResChunkData::SetComplete(), C4Network2ResCore::SetLoadable(), szFile, and szStandalone.

Referenced by C4Network2ResList::AddByFile(), C4Network2ResList::AddByGroup(), CalculateSHA(), FinishDerive(), IsBinaryCompatible(), and OpenFileRead().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getType()

C4Network2ResType C4Network2Res::getType ( ) const
inline

Definition at line 238 of file C4Network2Res.h.

238 { return Core.getType(); }
C4Network2ResType getType() const
Definition: C4Network2Res.h:84

References Core, and C4Network2ResCore::getType().

Referenced by Derive(), FinishDerive(), C4GameControlNetwork::OnResComplete(), and C4GameRes::SetNetRes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isAnonymous()

bool C4Network2Res::isAnonymous ( ) const
inline

Definition at line 241 of file C4Network2Res.h.

241 { return getResID() == C4NetResIDAnonymous; }
const int32_t C4NetResIDAnonymous
Definition: C4Network2Res.h:38

References C4NetResIDAnonymous, and getResID().

Referenced by FinishDerive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsBinaryCompatible()

bool C4Network2Res::IsBinaryCompatible ( )

Definition at line 534 of file C4Network2Res.cpp.

535 {
536  // returns wether the standalone of this resource is binary compatible
537  // to the official version (means: matches the file checksum)
538 
539  CStdLock FileLock(&FileCSec);
540  // standalone set? ok then (see GetStandalone)
541  if (szStandalone[0]) return true;
542  // is a directory?
543  if (DirectoryExists(szFile))
544  // forget it - if the file is packed now, the creation time and author
545  // won't match.
546  return false;
547  // try to create the standalone
548  return GetStandalone(nullptr, 0, false, false, true);
549 }

References DirectoryExists(), FileCSec, GetStandalone(), szFile, and szStandalone.

Referenced by C4Network2ResList::HandlePacket(), and OnDiscover().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isComplete()

bool C4Network2Res::isComplete ( ) const
inline

Definition at line 249 of file C4Network2Res.h.

249 { return !fLoading; }

References fLoading.

Referenced by C4PlayerInfo::LoadBigIcon().

Here is the caller graph for this function:

◆ isDirty()

bool C4Network2Res::isDirty ( ) const
inline

Definition at line 240 of file C4Network2Res.h.

240 { return fDirty; }

References fDirty.

Referenced by C4Network2ResList::OnTimer().

Here is the caller graph for this function:

◆ isLoading()

bool C4Network2Res::isLoading ( ) const
inline

Definition at line 248 of file C4Network2Res.h.

248 { return fLoading; }

References fLoading.

Referenced by Derive(), C4Network2ResList::OnTimer(), C4ControlJoinPlayer::PreExecute(), C4PlayerInfoList::RecreatePlayers(), and C4Network2::RetrieveRes().

Here is the caller graph for this function:

◆ isRemoved()

bool C4Network2Res::isRemoved ( ) const
inline

Definition at line 247 of file C4Network2Res.h.

247 { return fRemoved; }

References fRemoved.

Referenced by C4Network2ResList::OnTimer(), and C4ControlJoinPlayer::PreRec().

Here is the caller graph for this function:

◆ isTempFile()

bool C4Network2Res::isTempFile ( ) const
inline

Definition at line 251 of file C4Network2Res.h.

251 { return fTempFile; }

References fTempFile.

◆ NeedsDiscover()

bool C4Network2Res::NeedsDiscover ( )

Definition at line 942 of file C4Network2Res.cpp.

943 {
944  // loading, but no active load sources?
945  if (fLoading && !iLoadCnt)
946  {
947  // set timeout, if this is the first discover
948  if (!iDiscoverStartTime)
949  iDiscoverStartTime = time(nullptr);
950  // do discover
951  return true;
952  }
953  return false;
954 }

References fLoading, iDiscoverStartTime, and iLoadCnt.

Referenced by C4Network2ResList::OnTimer().

Here is the caller graph for this function:

◆ OnChunk()

void C4Network2Res::OnChunk ( const C4Network2ResChunk rChunk)

Definition at line 879 of file C4Network2Res.cpp.

880 {
881  if (!fLoading) return;
882  // correct resource?
883  if (rChunk.getResID() != getResID()) return;
884  // add resource data
885  CStdLock FileLock(&FileCSec);
886  bool fSuccess = rChunk.AddTo(this, pParent->getIOClass());
887 #ifdef C4NET2RES_DEBUG_LOG
888  // log
889  Application.InteractiveThread.ThreadLogS("Network: Res: %s chunk %d to resource %s (%s)%s", fSuccess ? "added" : "could not add", rChunk.getChunkNr(), Core.getFileName(), szFile, fSuccess ? "" : "!");
890 #endif
891  if (fSuccess)
892  {
893  // status changed
894  fDirty = true;
895  // remove load waits
896  for (C4Network2ResLoad *pLoad = pLoads, *pNext; pLoad; pLoad = pNext)
897  {
898  pNext = pLoad->Next();
899  if (static_cast<uint32_t>(pLoad->getChunk()) == rChunk.getChunkNr())
900  RemoveLoad(pLoad);
901  }
902  }
903  // complete?
904  if (Chunks.isComplete())
905  EndLoad();
906  // check: start new loads?
907  else
908  StartNewLoads();
909 }
uint32_t getChunkNr() const
bool AddTo(C4Network2Res *pRes, C4Network2IO *pIO) const
int32_t getResID() const

References C4Network2ResChunk::AddTo(), Application, Chunks, Core, EndLoad(), fDirty, FileCSec, fLoading, C4Network2ResChunk::getChunkNr(), C4Network2ResCore::getFileName(), C4Network2ResList::getIOClass(), getResID(), C4Network2ResChunk::getResID(), C4Application::InteractiveThread, C4Network2ResChunkData::isComplete(), pLoads, pNext, pParent, RemoveLoad(), StartNewLoads(), szFile, and C4InteractiveThread::ThreadLogS().

Referenced by C4Network2ResList::HandlePacket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnDiscover()

void C4Network2Res::OnDiscover ( C4Network2IOConnection pBy)

Definition at line 843 of file C4Network2Res.cpp.

844 {
845  if (!IsBinaryCompatible()) return;
846  // discovered
847  iLastReqTime = time(nullptr);
848  // send status back
849  SendStatus(pBy);
850 }
bool SendStatus(C4Network2IOConnection *pTo=nullptr)
bool IsBinaryCompatible()

References iLastReqTime, IsBinaryCompatible(), and SendStatus().

Here is the call graph for this function:

◆ OnStatus()

void C4Network2Res::OnStatus ( const C4Network2ResChunkData rChunkData,
C4Network2IOConnection pBy 
)

Definition at line 852 of file C4Network2Res.cpp.

853 {
854  if (!fLoading) return;
855  // discovered a source: reset timeout
856  iDiscoverStartTime = 0;
857  // check if the chunk data is valid
858  if (rChunkData.getChunkCnt() != Chunks.getChunkCnt())
859  return;
860  // add chunk data
861  ClientChunks *pChunks;
862  for (pChunks = pCChunks; pChunks; pChunks = pChunks->Next)
863  if (pChunks->ClientID == pBy->getClientID())
864  break;
865  // not found? add
866  if (!pChunks)
867  {
868  pChunks = new ClientChunks();
869  pChunks->Next = pCChunks;
870  pCChunks = pChunks;
871  }
872  pChunks->ClientID = pBy->getClientID();
873  pChunks->Chunks = rChunkData;
874  // check load
875  if (!StartLoad(pChunks->ClientID, pChunks->Chunks))
877 }
int32_t getChunkCnt() const
bool StartLoad(int32_t iFromClient, const C4Network2ResChunkData &Chunks)

References Chunks, C4Network2Res::ClientChunks::Chunks, C4Network2Res::ClientChunks::ClientID, fLoading, C4Network2ResChunkData::getChunkCnt(), C4Network2IOConnection::getClientID(), iDiscoverStartTime, C4Network2Res::ClientChunks::Next, pCChunks, RemoveCChunks(), and StartLoad().

Referenced by C4Network2ResList::HandlePacket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenAsGrp()

C4Group * C4Network2Res::OpenAsGrp ( ) const

Definition at line 779 of file C4Network2Res.cpp.

780 {
781  C4Group *pnGrp = new C4Group();
782  if (!pnGrp->Open(szFile))
783  {
784  delete pnGrp;
785  return nullptr;
786  }
787  return pnGrp;
788 }
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660

References C4Group::Open(), and szFile.

Here is the call graph for this function:

◆ OpenFileRead()

int32_t C4Network2Res::OpenFileRead ( )
protected

Definition at line 977 of file C4Network2Res.cpp.

978 {
979  CStdLock FileLock(&FileCSec);
980  if (!GetStandalone(nullptr, 0, false, false, true)) return -1;
981  // FIXME: Use standard OC file access api here
982 #ifdef _WIN32
983  return _wopen(GetWideChar(szStandalone), _O_BINARY | O_RDONLY);
984 #else
985  return open(szStandalone, _O_BINARY | O_CLOEXEC | O_RDONLY);
986 #endif
987 }
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
#define _O_BINARY
#define O_CLOEXEC

References _O_BINARY, FileCSec, GetStandalone(), GetWideChar(), O_CLOEXEC, and szStandalone.

Referenced by C4Network2ResChunk::Set().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenFileWrite()

int32_t C4Network2Res::OpenFileWrite ( )
protected

Definition at line 989 of file C4Network2Res.cpp.

990 {
991  CStdLock FileLock(&FileCSec);
992  // FIXME: Use standard OC file access api here
993 #ifdef _WIN32
994  return _wopen(GetWideChar(szStandalone), _O_BINARY | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
995 #else
996  return open(szStandalone, _O_BINARY | O_CLOEXEC | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
997 #endif
998 }

References _O_BINARY, FileCSec, GetWideChar(), O_CLOEXEC, and szStandalone.

Referenced by C4Network2ResChunk::AddTo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OptimizeStandalone()

bool C4Network2Res::OptimizeStandalone ( bool  fSilent)
protected

Definition at line 1141 of file C4Network2Res.cpp.

1142 {
1143  CStdLock FileLock(&FileCSec);
1144  // for now: player files only
1145  if (Core.getType() == NRT_Player)
1146  {
1147  // log - this may take a few seconds
1148  if (!fSilent) LogF(LoadResStr("IDS_PRC_NETPREPARING"), GetFilename(szFile));
1149  // copy to temp file, if needed
1150  if (!fTempFile && SEqual(szFile, szStandalone))
1151  {
1152  char szNewStandalone[_MAX_PATH_LEN];
1153  if (!pParent->FindTempResFileName(szStandalone, szNewStandalone))
1154  { if (!fSilent) Log("OptimizeStandalone: could not find free name for temporary file!"); return false; }
1155  if (!C4Group_CopyItem(szStandalone, szNewStandalone))
1156  { if (!fSilent) Log("OptimizeStandalone: could not copy to temporary file!"); return false; } /* TODO: Test failure */
1157  SCopy(szNewStandalone, szStandalone, sizeof(szStandalone) - 1);
1158  }
1159  // open as group
1160  C4Group Grp;
1161  if (!Grp.Open(szStandalone))
1162  { if (!fSilent) Log("OptimizeStandalone: could not open player file!"); return false; }
1163  // remove bigicon, if the file size is too large
1164  size_t iBigIconSize=0;
1165  if (Grp.FindEntry(C4CFN_BigIcon, nullptr, &iBigIconSize))
1166  if (iBigIconSize > C4NetResMaxBigicon*1024)
1167  Grp.Delete(C4CFN_BigIcon);
1168  Grp.Close();
1169  }
1170  return true;
1171 }
#define C4CFN_BigIcon
Definition: C4Components.h:111
@ NRT_Player
Definition: C4Network2Res.h:45
const int32_t C4NetResMaxBigicon
Definition: C4Network2Res.h:36
bool Close()
Definition: C4Group.cpp:971
bool Delete(const char *files, bool recursive=false)
Definition: C4Group.cpp:1645
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
Definition: C4Group.cpp:2211

References _MAX_PATH_LEN, C4CFN_BigIcon, C4Group_CopyItem(), C4NetResMaxBigicon, C4Group::Close(), Core, C4Group::Delete(), FileCSec, C4Group::FindEntry(), C4Network2ResList::FindTempResFileName(), fTempFile, GetFilename(), C4Network2ResCore::getType(), LoadResStr(), Log(), LogF(), NRT_Player, C4Group::Open(), pParent, SCopy(), SEqual(), szFile, and szStandalone.

Referenced by GetStandalone().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Remove()

void C4Network2Res::Remove ( )

Definition at line 790 of file C4Network2Res.cpp.

791 {
792  // schedule for removal
793  fRemoved = true;
794 }

References fRemoved.

Referenced by C4Network2ResList::OnTimer(), C4Network2::RemoveDynamic(), and C4Network2::RetrieveScenario().

Here is the caller graph for this function:

◆ RemoveCChunks()

void C4Network2Res::RemoveCChunks ( ClientChunks pChunks)
protected

Definition at line 1124 of file C4Network2Res.cpp.

1125 {
1126  if (pChunks == pCChunks)
1127  pCChunks = pChunks->Next;
1128  else
1129  {
1130  // find previous entry
1131  ClientChunks *pPrev;
1132  for (pPrev = pCChunks; pPrev && pPrev->Next != pChunks; pPrev = pPrev->Next) {}
1133  // remove
1134  if (pPrev)
1135  pPrev->Next = pChunks->Next;
1136  }
1137  // delete
1138  delete pChunks;
1139 }

References C4Network2Res::ClientChunks::Next, and pCChunks.

Referenced by ClearLoad(), OnStatus(), and StartNewLoads().

Here is the caller graph for this function:

◆ RemoveLoad()

void C4Network2Res::RemoveLoad ( C4Network2ResLoad pLoad)
protected

Definition at line 1106 of file C4Network2Res.cpp.

1107 {
1108  if (pLoad == pLoads)
1109  pLoads = pLoad->Next();
1110  else
1111  {
1112  // find previous entry
1113  C4Network2ResLoad *pPrev;
1114  for (pPrev = pLoads; pPrev && pPrev->Next() != pLoad; pPrev = pPrev->Next()) {}
1115  // remove
1116  if (pPrev)
1117  pPrev->pNext = pLoad->Next();
1118  }
1119  // delete
1120  delete pLoad;
1121  iLoadCnt--;
1122 }
C4Network2ResLoad * pNext
C4Network2ResLoad * Next() const

References iLoadCnt, C4Network2ResLoad::Next(), pLoads, and C4Network2ResLoad::pNext.

Referenced by ClearLoad(), DoLoad(), and OnChunk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveBackFile()

bool C4Network2Res::SaveBackFile ( )

◆ SendChunk()

bool C4Network2Res::SendChunk ( uint32_t  iChunk,
int32_t  iToClient 
)

Definition at line 813 of file C4Network2Res.cpp.

814 {
815  assert(pParent && pParent->getIOClass());
816  if (!szStandalone[0] || iChunk >= Core.getChunkCnt()) return false;
817  // find connection for given client (one of the rare uses of the data connection)
819  if (!pConn) return false;
820  // save last request time
821  iLastReqTime = time(nullptr);
822  // create packet
823  CStdLock FileLock(&FileCSec);
824  C4Network2ResChunk ResChunk;
825  ResChunk.Set(this, iChunk);
826  // send
827  bool fSuccess = pConn->Send(MkC4NetIOPacket(PID_NetResData, ResChunk));
828  pConn->DelRef();
829  return fSuccess;
830 }
@ PID_NetResData
Definition: C4PacketBase.h:133
bool Send(const C4NetIOPacket &rPkt)
C4Network2IOConnection * GetDataConnection(int iClientID)
bool Set(C4Network2Res *pRes, uint32_t iChunk)

References Core, C4Network2IOConnection::DelRef(), FileCSec, C4Network2ResCore::getChunkCnt(), C4Network2IO::GetDataConnection(), C4Network2ResList::getIOClass(), iLastReqTime, MkC4NetIOPacket(), PID_NetResData, pParent, C4Network2IOConnection::Send(), C4Network2ResChunk::Set(), and szStandalone.

Referenced by C4Network2ResList::HandlePacket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SendStatus()

bool C4Network2Res::SendStatus ( C4Network2IOConnection pTo = nullptr)

Definition at line 796 of file C4Network2Res.cpp.

797 {
798  // pack status
800  // to one client?
801  if (pTo)
802  return pTo->Send(Pkt);
803  else
804  {
805  // reset dirty flag
806  fDirty = false;
807  // broadcast status
808  assert(pParent && pParent->getIOClass());
809  return pParent->getIOClass()->BroadcastMsg(Pkt);
810  }
811 }
@ PID_NetResStat
Definition: C4PacketBase.h:130

References C4Network2IO::BroadcastMsg(), Chunks, Core, fDirty, C4Network2ResCore::getID(), C4Network2ResList::getIOClass(), MkC4NetIOPacket(), PID_NetResStat, pParent, and C4Network2IOConnection::Send().

Referenced by OnDiscover(), and C4Network2ResList::OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetByCore()

bool C4Network2Res::SetByCore ( const C4Network2ResCore nCore,
bool  fSilent = false,
const char *  szAsFilename = nullptr,
int32_t  iRecursion = 0 
)

Definition at line 422 of file C4Network2Res.cpp.

423 {
424  StdStrBuf sFilename;
425  // try open local file
426  const char *szFilename = szAsFilename ? szAsFilename : GetC4Filename(nCore.getFileName());
427  if (SetByFile(szFilename, false, nCore.getType(), nCore.getID(), nCore.getFileName(), fSilent))
428  {
429  // check contents checksum
430  if (Core.getContentsCRC() == nCore.getContentsCRC())
431  {
432  // set core
433  fDirty = true;
434  Core = nCore;
435  // ok then
436  return true;
437  }
438  }
439  // get and search for filename without specified folder (e.g., Castle.ocs when the opened game is Easy.ocf\Castle.ocs)
440  const char *szFilenameOnly = GetFilename(szFilename);
441  const char *szFilenameC4 = GetC4Filename(szFilename);
442  if (szFilenameOnly != szFilenameC4)
443  {
444  sFilename.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4));
445  sFilename.Append(szFilenameOnly);
446  if (SetByCore(nCore, fSilent, szFilenameOnly, Config.Network.MaxResSearchRecursion)) return true;
447  }
448  // if it could still not be set, try within all folders of root (ignoring special folders), and try as file outside the folder
449  // but do not recurse any deeper than set by config (default: One folder)
450  if (iRecursion >= Config.Network.MaxResSearchRecursion) return false;
451  StdStrBuf sSearchPath; const char *szSearchPath;
452  if (!iRecursion)
453  szSearchPath = Config.General.ExePath.getData();
454  else
455  {
456  sSearchPath.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4));
457  szSearchPath = sSearchPath.getData();
458  }
459  StdStrBuf sNetPath; sNetPath.Copy(Config.Network.WorkPath);
460  char *szNetPath = sNetPath.GrabPointer();
461  TruncateBackslash(szNetPath);
462  sNetPath.Take(szNetPath);
463  for (DirectoryIterator i(szSearchPath); *i; ++i)
464  if (DirectoryExists(*i))
465  if (!*GetExtension(*i)) // directories without extension only
466  if (!szNetPath || !*szNetPath || !ItemIdentical(*i, szNetPath)) // ignore network path
467  {
468  // search for complete name at subpath (e.g. MyFolder\Easy.ocf\Castle.ocs)
469  sFilename.Format("%s%c%s", *i, DirectorySeparator, szFilenameC4);
470  if (SetByCore(nCore, fSilent, sFilename.getData(), iRecursion + 1))
471  return true;
472  }
473  // file could not be found locally
474  return false;
475 }
#define DirectorySeparator
size_t SLen(const char *sptr)
Definition: Standard.h:74
const char * GetC4Filename(const char *szPath)
Definition: StdFile.cpp:68
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
Definition: StdFile.cpp:879
void TruncateBackslash(char *szFilename)
Definition: StdFile.cpp:263
StdCopyStrBuf ExePath
Definition: C4Config.h:54
C4ConfigGeneral General
Definition: C4Config.h:255
char WorkPath[CFG_MaxString+1]
Definition: C4Config.h:145
int32_t MaxResSearchRecursion
Definition: C4Config.h:144
uint32_t getContentsCRC() const
Definition: C4Network2Res.h:91
bool SetByCore(const C4Network2ResCore &nCore, bool fSilent=false, const char *szAsFilename=nullptr, int32_t iRecursion=0)
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
void Take(char *pnData)
Definition: StdBuf.h:457
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
char * GrabPointer()
Definition: StdBuf.h:459

References StdStrBuf::Append(), Config, StdStrBuf::Copy(), Core, DirectoryExists(), DirectorySeparator, C4ConfigGeneral::ExePath, fDirty, StdStrBuf::Format(), C4Config::General, GetC4Filename(), C4Network2ResCore::getContentsCRC(), StdStrBuf::getData(), GetExtension(), C4Network2ResCore::getFileName(), GetFilename(), C4Network2ResCore::getID(), C4Network2ResCore::getType(), StdStrBuf::GrabPointer(), ItemIdentical(), C4ConfigNetwork::MaxResSearchRecursion, C4Config::Network, SetByFile(), SLen(), StdStrBuf::Take(), TruncateBackslash(), and C4ConfigNetwork::WorkPath.

Referenced by C4Network2ResList::AddByCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetByFile()

bool C4Network2Res::SetByFile ( const char *  strFilePath,
bool  fTemp,
C4Network2ResType  eType,
int32_t  iResID,
const char *  szResName = nullptr,
bool  fSilent = false 
)

Definition at line 357 of file C4Network2Res.cpp.

358 {
359  CStdLock FileLock(&FileCSec);
360  // default resource name: relative path
361  if (!szResName) szResName = Config.AtRelativePath(strFilePath);
362  SCopy(strFilePath, szFile, sizeof(szFile)-1);
363  // group?
364  C4Group Grp;
365  if (Reloc.Open(Grp, strFilePath))
366  return SetByGroup(&Grp, fTemp, eType, iResID, szResName, fSilent);
367  // so it needs to be a file
368  StdStrBuf szFullFile;
369  if (!Reloc.LocateItem(szFile, szFullFile))
370  { if (!fSilent) LogF("SetByFile: file %s not found!", strFilePath); return false; }
371  // calc checksum
372  uint32_t iCRC32;
373  if (!GetFileCRC(szFullFile.getData(), &iCRC32)) return false;
374 #ifdef C4NET2RES_DEBUG_LOG
375  // log
376  LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, szResName, szFile, fTemp ? "temp" : "static");
377 #endif
378  // set core
379  Core.Set(eType, iResID, Config.AtRelativePath(szFullFile.getData()), iCRC32);
380  // set own data
381  fDirty = true;
382  fTempFile = fTemp;
383  fStandaloneFailed = false;
384  fRemoved = false;
385  iLastReqTime = time(nullptr);
386  fLoading = false;
387  // ok
388  return true;
389 }
C4Reloc Reloc
Definition: C4Reloc.cpp:21
const char * AtRelativePath(const char *filename)
Definition: C4Config.cpp:741
void Set(C4Network2ResType eType, int32_t iResID, const char *strFileName, uint32_t iContentsCRC)
bool SetByGroup(C4Group *pGrp, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
bool LocateItem(const char *filename, StdStrBuf &str) const
Definition: C4Reloc.cpp:174
bool Open(C4Group &group, const char *filename) const
Definition: C4Reloc.cpp:156

References C4Config::AtRelativePath(), Config, Core, fDirty, FileCSec, fLoading, fRemoved, fStandaloneFailed, fTempFile, StdStrBuf::getData(), GetFileCRC(), iLastReqTime, C4Reloc::LocateItem(), LogF(), LogSilentF(), C4Reloc::Open(), Reloc, SCopy(), C4Network2ResCore::Set(), SetByGroup(), and szFile.

Referenced by C4Network2ResList::AddByFile(), FinishDerive(), and SetByCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetByGroup()

bool C4Network2Res::SetByGroup ( C4Group pGrp,
bool  fTemp,
C4Network2ResType  eType,
int32_t  iResID,
const char *  szResName = nullptr,
bool  fSilent = false 
)

Definition at line 391 of file C4Network2Res.cpp.

392 {
393  Clear();
394  CStdLock FileLock(&FileCSec);
395  // default resource name: relative path
396  StdStrBuf sResName;
397  if (szResName)
398  sResName = szResName;
399  else
400  {
401  StdStrBuf sFullName = pGrp->GetFullName();
402  sResName.Copy(Config.AtRelativePath(sFullName.getData()));
403  }
404  SCopy(pGrp->GetFullName().getData(), szFile, sizeof(szFile)-1);
405  // set core
406  Core.Set(eType, iResID, sResName.getData(), pGrp->EntryCRC32());
407 #ifdef C4NET2RES_DEBUG_LOG
408  // log
409  LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, sResName.getData(), szFile, fTemp ? "temp" : "static");
410 #endif
411  // set data
412  fDirty = true;
413  fTempFile = fTemp;
414  fStandaloneFailed = false;
415  fRemoved = false;
416  iLastReqTime = time(nullptr);
417  fLoading = false;
418  // ok
419  return true;
420 }
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
unsigned int EntryCRC32(const char *wildcard=nullptr)
Definition: C4Group.cpp:2354

References C4Config::AtRelativePath(), Clear(), Config, StdStrBuf::Copy(), Core, C4Group::EntryCRC32(), fDirty, FileCSec, fLoading, fRemoved, fStandaloneFailed, fTempFile, StdStrBuf::getData(), C4Group::GetFullName(), iLastReqTime, LogSilentF(), SCopy(), C4Network2ResCore::Set(), and szFile.

Referenced by C4Network2ResList::AddByGroup(), and SetByFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetDerived()

bool C4Network2Res::SetDerived ( const char *  strName,
const char *  strFilePath,
bool  fTemp,
C4Network2ResType  eType,
int32_t  iDResID 
)

Definition at line 507 of file C4Network2Res.cpp.

508 {
509  Clear();
510  CStdLock FileLock(&FileCSec);
511  // set core
512  Core.Set(eType, C4NetResIDAnonymous, strName, ~0);
513  Core.SetDerived(iDResID);
514  // save file path
515  SCopy(strFilePath, szFile, _MAX_PATH);
516  *szStandalone = '\0';
517  // set flags
518  fDirty = false;
519  fTempFile = fTemp;
520  fStandaloneFailed = false;
521  fRemoved = false;
522  iLastReqTime = time(nullptr);
523  fLoading = false;
524  // Do not set any chunk data - anonymous resources are very likely to change.
525  // Wait for FinishDerived()-call.
526  return true;
527 }

References _MAX_PATH, C4NetResIDAnonymous, Clear(), Core, fDirty, FileCSec, fLoading, fRemoved, fStandaloneFailed, fTempFile, iLastReqTime, SCopy(), C4Network2ResCore::Set(), C4Network2ResCore::SetDerived(), szFile, and szStandalone.

Referenced by Derive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetLoad()

bool C4Network2Res::SetLoad ( const C4Network2ResCore nCore)

Definition at line 477 of file C4Network2Res.cpp.

478 {
479  Clear();
480  CStdLock FileLock(&FileCSec);
481  // must be loadable
482  if (!nCore.isLoadable()) return false;
483  // save core, set chunks
484  Core = nCore;
486  // create temporary file
488  return false;
489 #ifdef C4NET2RES_DEBUG_LOG
490  // log
491  Application.InteractiveThread.ThreadLogS("Network: Resource: loading %d:%s to file %s", Core.getID(), Core.getFileName(), szFile);
492 #endif
493  // set standalone (result is going to be binary-compatible)
494  SCopy(szFile, szStandalone, sizeof(szStandalone) - 1);
495  // set flags
496  fDirty = false;
497  fTempFile = true;
498  fStandaloneFailed = false;
499  fRemoved = false;
500  iLastReqTime = time(nullptr);
501  fLoading = true;
502  // No discovery yet
503  iDiscoverStartTime = 0;
504  return true;
505 }
void SetIncomplete(int32_t iChunkCnt)

References Application, Chunks, Clear(), Core, fDirty, FileCSec, C4Network2ResList::FindTempResFileName(), fLoading, fRemoved, fStandaloneFailed, fTempFile, C4Network2ResCore::getChunkCnt(), C4Network2ResCore::getFileName(), C4Network2ResCore::getID(), iDiscoverStartTime, iLastReqTime, C4Application::InteractiveThread, C4Network2ResCore::isLoadable(), pParent, SCopy(), C4Network2ResChunkData::SetIncomplete(), szFile, szStandalone, and C4InteractiveThread::ThreadLogS().

Referenced by C4Network2ResList::AddLoad().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StartLoad()

bool C4Network2Res::StartLoad ( int32_t  iFromClient,
const C4Network2ResChunkData Chunks 
)
protected

Definition at line 1047 of file C4Network2Res.cpp.

1048 {
1049  assert(pParent && pParent->getIOClass());
1050  // all slots used? ignore
1051  if (iLoadCnt + 1 >= C4NetResMaxLoad) return true;
1052  // is there already a load by this client? ignore
1053  for (C4Network2ResLoad *pPos = pLoads; pPos; pPos = pPos->Next())
1054  if (pPos->getByClient() == iFromClient)
1055  return true;
1056  // find chunk to retrieve
1057  int32_t iLoads[C4NetResMaxLoad]; int32_t i = 0;
1058  for (C4Network2ResLoad *pLoad = pLoads; pLoad; pLoad = pLoad->Next())
1059  iLoads[i++] = pLoad->getChunk();
1060  int32_t iRetrieveChunk = Chunks.GetChunkToRetrieve(Available, i, iLoads);
1061  // nothing? ignore
1062  if (iRetrieveChunk < 0 || (uint32_t)iRetrieveChunk >= Core.getChunkCnt())
1063  return true;
1064  // search message connection for client
1065  C4Network2IOConnection *pConn = pParent->getIOClass()->GetMsgConnection(iFromClient);
1066  if (!pConn) return false;
1067  // send request
1068  if (!pConn->Send(MkC4NetIOPacket(PID_NetResReq, C4PacketResRequest(Core.getID(), iRetrieveChunk))))
1069  { pConn->DelRef(); return false; }
1070  pConn->DelRef();
1071 #ifdef C4NET2RES_DEBUG_LOG
1072  // log
1073  Application.InteractiveThread.ThreadLogS("Network: Res: requesting chunk %d of %d:%s (%s) from client %d",
1074  iRetrieveChunk, Core.getID(), Core.getFileName(), szFile, iFromClient);
1075 #endif
1076  // create load class
1077  C4Network2ResLoad *pnLoad = new C4Network2ResLoad(iRetrieveChunk, iFromClient);
1078  // add to list
1079  pnLoad->pNext = pLoads;
1080  pLoads = pnLoad;
1081  iLoadCnt++;
1082  // ok
1083  return true;
1084 }
const int32_t C4NetResMaxLoad
Definition: C4Network2Res.h:33
@ PID_NetResReq
Definition: C4PacketBase.h:132
C4Network2IOConnection * GetMsgConnection(int iClientID)
int32_t GetChunkToRetrieve(const C4Network2ResChunkData &Available, int32_t iLoadingCnt, int32_t *pLoading) const

References Application, C4NetResMaxLoad, Chunks, Core, C4Network2IOConnection::DelRef(), C4Network2ResCore::getChunkCnt(), C4Network2ResChunkData::GetChunkToRetrieve(), C4Network2ResCore::getFileName(), C4Network2ResCore::getID(), C4Network2ResList::getIOClass(), C4Network2IO::GetMsgConnection(), iLoadCnt, C4Application::InteractiveThread, MkC4NetIOPacket(), C4Network2ResLoad::Next(), PID_NetResReq, pLoads, C4Network2ResLoad::pNext, pParent, C4Network2IOConnection::Send(), szFile, and C4InteractiveThread::ThreadLogS().

Referenced by OnStatus(), and StartNewLoads().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StartNewLoads()

void C4Network2Res::StartNewLoads ( )
protected

Definition at line 1000 of file C4Network2Res.cpp.

1001 {
1002  if (!pCChunks) return;
1003  // count clients
1004  int32_t iCChunkCnt = 0; ClientChunks *pChunks;
1005  for (pChunks = pCChunks; pChunks; pChunks = pChunks->Next)
1006  iCChunkCnt++;
1007  // create array
1008  ClientChunks **pC = new ClientChunks *[iCChunkCnt];
1009  // initialize
1010  int32_t i;
1011  for (i = 0; i < iCChunkCnt; i++) pC[i] = nullptr;
1012  // create shuffled order
1013  for (pChunks = pCChunks, i = 0; i < iCChunkCnt; i++, pChunks = pChunks->Next)
1014  {
1015  // determine position
1016  int32_t iPos = UnsyncedRandom(iCChunkCnt - i);
1017  // find & set
1018  for (int32_t j = 0; ; j++)
1019  if (!pC[j] && !iPos--)
1020  {
1021  pC[j] = pChunks;
1022  break;
1023  }
1024  }
1025  // start new load until maximum count reached
1026  while (iLoadCnt + 1 <= C4NetResMaxLoad)
1027  {
1028  int32_t ioLoadCnt = iLoadCnt;
1029  // search someone
1030  for (i = 0; i < iCChunkCnt; i++)
1031  if (pC[i])
1032  {
1033  // try to start load
1034  if (!StartLoad(pC[i]->ClientID, pC[i]->Chunks))
1035  { RemoveCChunks(pC[i]); pC[i] = nullptr; continue; }
1036  // success?
1037  if (iLoadCnt > ioLoadCnt) break;
1038  }
1039  // not found?
1040  if (i >= iCChunkCnt)
1041  break;
1042  }
1043  // clear up
1044  delete [] pC;
1045 }
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58

References C4NetResMaxLoad, Chunks, iLoadCnt, C4Network2Res::ClientChunks::Next, pCChunks, RemoveCChunks(), StartLoad(), and UnsyncedRandom().

Referenced by DoLoad(), and OnChunk().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ C4Network2ResChunk

friend class C4Network2ResChunk
friend

Definition at line 181 of file C4Network2Res.h.

◆ C4Network2ResList

friend class C4Network2ResList
friend

Definition at line 180 of file C4Network2Res.h.

Member Data Documentation

◆ Chunks

◆ Core

◆ fDirty

bool C4Network2Res::fDirty
protected

◆ FileCSec

◆ fLoading

bool C4Network2Res::fLoading
protected

◆ fRemoved

bool C4Network2Res::fRemoved
protected

Definition at line 220 of file C4Network2Res.h.

Referenced by Clear(), isRemoved(), Remove(), SetByFile(), SetByGroup(), SetDerived(), and SetLoad().

◆ fStandaloneFailed

bool C4Network2Res::fStandaloneFailed
protected

Definition at line 216 of file C4Network2Res.h.

Referenced by GetStandalone(), SetByFile(), SetByGroup(), SetDerived(), and SetLoad().

◆ fTempFile

bool C4Network2Res::fTempFile
protected

◆ iDiscoverStartTime

time_t C4Network2Res::iDiscoverStartTime
protected

Definition at line 229 of file C4Network2Res.h.

Referenced by ClearLoad(), DoLoad(), NeedsDiscover(), OnStatus(), and SetLoad().

◆ iLastReqTime

int32_t C4Network2Res::iLastReqTime
protected

◆ iLoadCnt

int32_t C4Network2Res::iLoadCnt
protected

Definition at line 231 of file C4Network2Res.h.

Referenced by ClearLoad(), DoLoad(), NeedsDiscover(), RemoveLoad(), StartLoad(), and StartNewLoads().

◆ iRefCnt

std::atomic_long C4Network2Res::iRefCnt
protected

Definition at line 219 of file C4Network2Res.h.

Referenced by AddRef(), and DelRef().

◆ pCChunks

struct C4Network2Res::ClientChunks * C4Network2Res::pCChunks
protected

◆ pLoads

C4Network2ResLoad* C4Network2Res::pLoads
protected

Definition at line 230 of file C4Network2Res.h.

Referenced by ClearLoad(), DoLoad(), OnChunk(), RemoveLoad(), and StartLoad().

◆ pNext

◆ pParent

C4Network2ResList* C4Network2Res::pParent
protected

◆ szFile

◆ szStandalone


The documentation for this class was generated from the following files: