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+1]
 
char szStandalone [_MAX_PATH+1]
 
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.

References szFile, and szStandalone.

Referenced by Derive().

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 }
bool fStandaloneFailed
int32_t iLastReqTime
time_t iDiscoverStartTime
int32_t iLoadCnt
struct C4Network2Res::ClientChunks * pCChunks
char szStandalone[_MAX_PATH+1]
C4Network2ResList * pParent
char szFile[_MAX_PATH+1]
C4Network2ResLoad * pLoads
std::atomic_long iRefCnt
C4Network2Res * pNext
Here is the caller graph for this function:

◆ ~C4Network2Res()

C4Network2Res::~C4Network2Res ( )

Definition at line 351 of file C4Network2Res.cpp.

References Clear(), and pNext.

352 {
353  assert(!pNext);
354  Clear();
355 }
C4Network2Res * pNext
Here is the call graph for this function:

Member Function Documentation

◆ AddRef()

void C4Network2Res::AddRef ( )

Definition at line 830 of file C4Network2Res.cpp.

References iRefCnt.

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

831 {
832  ++iRefCnt;
833 }
std::atomic_long iRefCnt
Here is the caller graph for this function:

◆ CalculateSHA()

bool C4Network2Res::CalculateSHA ( )

Definition at line 655 of file C4Network2Res.cpp.

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

Referenced by C4GameRes::CalcHash().

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

References Core, and C4Network2ResCore::SetID().

530 {
531  Core.SetID(inID);
532 }
C4Network2ResCore Core
void SetID(int32_t inID)
Definition: C4Network2Res.h:99
Here is the call graph for this function:

◆ Clear()

void C4Network2Res::Clear ( )

Definition at line 954 of file C4Network2Res.cpp.

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().

955 {
956  CStdLock FileLock(&FileCSec);
957  // delete files
958  if (fTempFile)
959  if (FileExists(szFile))
960  if (!EraseFile(szFile))
961  LogSilentF("Network: Could not delete temporary resource file (%s)", strerror(errno));
962  if (szStandalone[0] && !SEqual(szFile, szStandalone))
964  if (!EraseFile(szStandalone))
965  LogSilentF("Network: Could not delete temporary resource file (%s)", strerror(errno));
966  szFile[0] = szStandalone[0] = '\0';
967  fDirty = false;
968  fTempFile = false;
969  Core.Clear();
970  Chunks.Clear();
971  fRemoved = false;
972  ClearLoad();
973 }
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:270
C4Network2ResCore Core
bool EraseFile(const char *szFileName)
bool FileExists(const char *szFileName)
char szStandalone[_MAX_PATH+1]
char szFile[_MAX_PATH+1]
C4Network2ResChunkData Chunks
CStdCSec FileCSec
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearLoad()

void C4Network2Res::ClearLoad ( )
protected

Definition at line 1095 of file C4Network2Res.cpp.

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

Referenced by Clear(), and EndLoad().

1096 {
1097  // remove client chunks and loads
1098  fLoading = false;
1099  while (pCChunks) RemoveCChunks(pCChunks);
1100  while (pLoads) RemoveLoad(pLoads);
1102 }
void RemoveLoad(C4Network2ResLoad *pLoad)
time_t iDiscoverStartTime
int32_t iLoadCnt
struct C4Network2Res::ClientChunks * pCChunks
void RemoveCChunks(ClientChunks *pChunks)
C4Network2ResLoad * pLoads
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DelRef()

void C4Network2Res::DelRef ( )

Definition at line 835 of file C4Network2Res.cpp.

References iRefCnt.

836 {
837  if (--iRefCnt == 0)
838  delete this;
839 }
std::atomic_long iRefCnt

◆ Derive()

C4Network2Res::Ref C4Network2Res::Derive ( )

Definition at line 674 of file C4Network2Res.cpp.

References _MAX_PATH, 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().

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

◆ DoLoad()

bool C4Network2Res::DoLoad ( )

Definition at line 909 of file C4Network2Res.cpp.

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

Referenced by C4Network2ResList::OnTimer().

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

◆ EndLoad()

void C4Network2Res::EndLoad ( )
protected

Definition at line 1084 of file C4Network2Res.cpp.

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

Referenced by OnChunk().

1085 {
1086  // clear loading data
1087  ClearLoad();
1088  // set complete
1089  fLoading = false;
1090  // call handler
1091  assert(pParent);
1092  pParent->OnResComplete(this);
1093 }
void OnResComplete(C4Network2Res *pRes)
C4Network2ResList * pParent
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 730 of file C4Network2Res.cpp.

References _MAX_PATH, 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.

731 {
732  // All changes have been made. Register this resource with a new ID.
733 
734  // security
735  if (!isAnonymous()) return false;
736 
737  CStdLock FileLock(&FileCSec);
738  // Save back data
739  int32_t iDerID = Core.getDerID();
740  char szName[_MAX_PATH+1]; SCopy(Core.getFileName(), szName, _MAX_PATH);
741  char szFileC[_MAX_PATH+1]; SCopy(szFile, szFileC, _MAX_PATH);
742  // Set by file
743  if (!SetByFile(szFileC, fTempFile, getType(), pParent->nextResID(), szName))
744  return false;
745  // create standalone
746  if (!GetStandalone(nullptr, 0, true))
747  return false;
748  // Set ID
749  Core.SetDerived(iDerID);
750  // announce derive
752  // derivation is dirty bussines
753  fDirty = true;
754  // ok
755  return true;
756 }
bool SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
C4Network2ResType getType() const
#define _MAX_PATH
C4Network2IO * getIOClass()
C4Network2ResCore Core
C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr=C4NetIO::addr_t())
Definition: C4PacketBase.h:40
bool isAnonymous() const
void SetDerived(int32_t inDerID)
bool BroadcastMsg(const C4NetIOPacket &rPkt)
bool GetStandalone(char *pTo, int32_t iMaxL, bool fSetOfficial, bool fAllowUnloadable=false, bool fSilent=false)
C4Network2ResList * pParent
char szFile[_MAX_PATH+1]
CStdCSec FileCSec
int32_t getDerID() const
Definition: C4Network2Res.h:87
const char * getFileName() const
Definition: C4Network2Res.h:94
Here is the call graph for this function:

◆ FinishDerive() [2/2]

bool C4Network2Res::FinishDerive ( const C4Network2ResCore nCore)

Definition at line 758 of file C4Network2Res.cpp.

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

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

◆ getCore()

const C4Network2ResCore& C4Network2Res::getCore ( ) const
inline

Definition at line 239 of file C4Network2Res.h.

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

239 { return Core; }
C4Network2ResCore Core
Here is the caller graph for this function:

◆ getFile()

const char* C4Network2Res::getFile ( ) const
inline

Definition at line 244 of file C4Network2Res.h.

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

244 { return szFile; }
char szFile[_MAX_PATH+1]
Here is the caller graph for this function:

◆ getFileCSec()

CStdCSec* C4Network2Res::getFileCSec ( )
inline

Definition at line 245 of file C4Network2Res.h.

245 { return &FileCSec; }
CStdCSec FileCSec

◆ getLastReqTime()

int32_t C4Network2Res::getLastReqTime ( ) const
inline

Definition at line 246 of file C4Network2Res.h.

246 { return iLastReqTime; }
int32_t iLastReqTime

◆ getPresentPercent()

int32_t C4Network2Res::getPresentPercent ( ) const
inline

Definition at line 250 of file C4Network2Res.h.

References C4Network2ResChunkData::getPresentPercent().

Referenced by C4Network2::RetrieveRes(), and C4GameLobby::ScenDesc::ScenDesc().

250 { return fLoading ? Chunks.getPresentPercent() : 100; }
int32_t getPresentPercent() const
C4Network2ResChunkData Chunks
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.

References C4Network2ResCore::getID().

243 { return Core.getID() >> 16; }
C4Network2ResCore Core
int32_t getID() const
Definition: C4Network2Res.h:86
Here is the call graph for this function:

◆ getResID()

int32_t C4Network2Res::getResID ( ) const
inline

Definition at line 242 of file C4Network2Res.h.

References C4Network2ResCore::getID().

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

242 { return Core.getID(); }
C4Network2ResCore Core
int32_t getID() const
Definition: C4Network2Res.h:86
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.

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().

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  // sorry, this version isn't good enough :(
630  return false;
631  }
632 
633  // calc checksum
634  uint32_t iCRC32;
635  if (!GetFileCRC(szStandalone, &iCRC32))
636  { if (!fSilent) Log("GetStandalone: could not calculate checksum!"); return false; }
637  // set / check
638  if (!fSetOfficial && iCRC32 != Core.getFileCRC())
639  {
640  // remove file, return
642  return false;
643  }
644 
645  // we didn't fail
646  fStandaloneFailed = false;
647  // mark resource as loadable and safe file information
648  Core.SetLoadable(iSize, iCRC32);
649  // set up chunk data
651  // ok
652  return true;
653 }
char * GetFilename(char *szPath)
Definition: StdFile.cpp:45
bool fStandaloneFailed
C4Config Config
Definition: C4Config.cpp:833
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
static bool GetDirSize(const char *szPath, uint32_t *pSize, uint32_t inMaxSize=~0)
int32_t MaxLoadFileSize
Definition: C4Config.h:157
uint32_t getChunkCnt() const
Definition: C4Network2Res.h:96
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool C4Group_PackDirectoryTo(const char *szFilename, const char *szFilenameTo)
Definition: C4Group.cpp:221
size_t FileSize(const char *fname)
bool GetFileCRC(const char *szFilename, uint32_t *pCRC32)
Definition: CStdFile.cpp:355
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:270
C4Network2ResCore Core
uint32_t getFileSize() const
Definition: C4Network2Res.h:89
bool C4Group_CopyItem(const char *szSource, const char *szTarget1, bool fNoSort, bool fResetAttributes)
Definition: C4Group.cpp:100
bool EraseDirectory(const char *szDirName)
Definition: StdFile.cpp:761
C4ConfigNetwork Network
Definition: C4Config.h:255
bool FindTempResFileName(const char *szFilename, char *pTarget)
bool FileExists(const char *szFileName)
void SetLoadable(uint32_t iSize, uint32_t iCRC)
char szStandalone[_MAX_PATH+1]
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:684
C4Network2ResList * pParent
bool isLoadable() const
Definition: C4Network2Res.h:88
char szFile[_MAX_PATH+1]
uint32_t getFileCRC() const
Definition: C4Network2Res.h:90
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:809
bool Log(const char *szMessage)
Definition: C4Log.cpp:202
C4Network2ResChunkData Chunks
bool OptimizeStandalone(bool fSilent)
void SetComplete(int32_t iChunkCnt)
CStdCSec FileCSec
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:260
bool C4Group_PackDirectory(const char *szFilename)
Definition: C4Group.cpp:284
int iSize
Definition: TstC4NetIO.cpp:32
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.

References C4Network2ResCore::getType().

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

238 { return Core.getType(); }
C4Network2ResType getType() const
Definition: C4Network2Res.h:84
C4Network2ResCore Core
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.

References C4NetResIDAnonymous.

Referenced by FinishDerive().

241 { return getResID() == C4NetResIDAnonymous; }
const int32_t C4NetResIDAnonymous
Definition: C4Network2Res.h:38
int32_t getResID() const
Here is the caller graph for this function:

◆ IsBinaryCompatible()

bool C4Network2Res::IsBinaryCompatible ( )

Definition at line 534 of file C4Network2Res.cpp.

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

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

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 }
bool GetStandalone(char *pTo, int32_t iMaxL, bool fSetOfficial, bool fAllowUnloadable=false, bool fSilent=false)
char szStandalone[_MAX_PATH+1]
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:684
char szFile[_MAX_PATH+1]
CStdCSec FileCSec
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.

Referenced by C4ControlJoinPlayer::C4ControlJoinPlayer(), C4PlayerInfo::LoadBigIcon(), and C4GameLobby::ScenDesc::ScenDesc().

249 { return !fLoading; }
Here is the caller graph for this function:

◆ isDirty()

bool C4Network2Res::isDirty ( ) const
inline

Definition at line 240 of file C4Network2Res.h.

Referenced by C4Network2ResList::OnTimer().

240 { return fDirty; }
Here is the caller graph for this function:

◆ isLoading()

bool C4Network2Res::isLoading ( ) const
inline

Definition at line 248 of file C4Network2Res.h.

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

248 { return fLoading; }
Here is the caller graph for this function:

◆ isRemoved()

bool C4Network2Res::isRemoved ( ) const
inline

Definition at line 247 of file C4Network2Res.h.

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

247 { return fRemoved; }
Here is the caller graph for this function:

◆ isTempFile()

bool C4Network2Res::isTempFile ( ) const
inline

Definition at line 251 of file C4Network2Res.h.

References C4Network2ResCore::Clear(), C4Network2ResCore::eType, and C4Network2ResCore::SetDerived().

251 { return fTempFile; }
Here is the call graph for this function:

◆ NeedsDiscover()

bool C4Network2Res::NeedsDiscover ( )

Definition at line 940 of file C4Network2Res.cpp.

References fLoading, iDiscoverStartTime, and iLoadCnt.

Referenced by C4Network2ResList::OnTimer().

941 {
942  // loading, but no active load sources?
943  if (fLoading && !iLoadCnt)
944  {
945  // set timeout, if this is the first discover
946  if (!iDiscoverStartTime)
947  iDiscoverStartTime = time(nullptr);
948  // do discover
949  return true;
950  }
951  return false;
952 }
time_t iDiscoverStartTime
int32_t iLoadCnt
Here is the caller graph for this function:

◆ OnChunk()

void C4Network2Res::OnChunk ( const C4Network2ResChunk rChunk)

Definition at line 877 of file C4Network2Res.cpp.

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().

878 {
879  if (!fLoading) return;
880  // correct resource?
881  if (rChunk.getResID() != getResID()) return;
882  // add resource data
883  CStdLock FileLock(&FileCSec);
884  bool fSuccess = rChunk.AddTo(this, pParent->getIOClass());
885 #ifdef C4NET2RES_DEBUG_LOG
886  // log
887  Application.InteractiveThread.ThreadLogS("Network: Res: %s chunk %d to resource %s (%s)%s", fSuccess ? "added" : "could not add", rChunk.getChunkNr(), Core.getFileName(), szFile, fSuccess ? "" : "!");
888 #endif
889  if (fSuccess)
890  {
891  // status changed
892  fDirty = true;
893  // remove load waits
894  for (C4Network2ResLoad *pLoad = pLoads, *pNext; pLoad; pLoad = pNext)
895  {
896  pNext = pLoad->Next();
897  if (static_cast<uint32_t>(pLoad->getChunk()) == rChunk.getChunkNr())
898  RemoveLoad(pLoad);
899  }
900  }
901  // complete?
902  if (Chunks.isComplete())
903  EndLoad();
904  // check: start new loads?
905  else
906  StartNewLoads();
907 }
void RemoveLoad(C4Network2ResLoad *pLoad)
bool ThreadLogS(const char *szMessage,...) GNUC_FORMAT_ATTRIBUTE_O
C4Network2IO * getIOClass()
C4Network2ResCore Core
uint32_t getChunkNr() const
int32_t getResID() const
bool AddTo(C4Network2Res *pRes, C4Network2IO *pIO) const
C4Network2ResList * pParent
int32_t getResID() const
char szFile[_MAX_PATH+1]
C4Network2ResChunkData Chunks
C4Network2ResLoad * pLoads
CStdCSec FileCSec
C4Application Application
Definition: C4Globals.cpp:44
C4InteractiveThread InteractiveThread
Definition: C4Application.h:45
C4Network2Res * pNext
const char * getFileName() const
Definition: C4Network2Res.h:94
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 841 of file C4Network2Res.cpp.

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

842 {
843  if (!IsBinaryCompatible()) return;
844  // discovered
845  iLastReqTime = time(nullptr);
846  // send status back
847  SendStatus(pBy);
848 }
int32_t iLastReqTime
bool IsBinaryCompatible()
bool SendStatus(C4Network2IOConnection *pTo=nullptr)
Here is the call graph for this function:

◆ OnStatus()

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

Definition at line 850 of file C4Network2Res.cpp.

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().

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

◆ OpenAsGrp()

C4Group * C4Network2Res::OpenAsGrp ( ) const

Definition at line 777 of file C4Network2Res.cpp.

References C4Group::Open(), and szFile.

778 {
779  C4Group *pnGrp = new C4Group();
780  if (!pnGrp->Open(szFile))
781  {
782  delete pnGrp;
783  return nullptr;
784  }
785  return pnGrp;
786 }
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
char szFile[_MAX_PATH+1]
Here is the call graph for this function:

◆ OpenFileRead()

int32_t C4Network2Res::OpenFileRead ( )
protected

Definition at line 975 of file C4Network2Res.cpp.

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

Referenced by C4Network2ResChunk::Set().

976 {
977  CStdLock FileLock(&FileCSec);
978  if (!GetStandalone(nullptr, 0, false, false, true)) return -1;
979  // FIXME: Use standard OC file access api here
980 #ifdef _WIN32
981  return _wopen(GetWideChar(szStandalone), _O_BINARY | O_RDONLY);
982 #else
983  return open(szStandalone, _O_BINARY | O_CLOEXEC | O_RDONLY);
984 #endif
985 }
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
#define O_CLOEXEC
bool GetStandalone(char *pTo, int32_t iMaxL, bool fSetOfficial, bool fAllowUnloadable=false, bool fSilent=false)
char szStandalone[_MAX_PATH+1]
#define _O_BINARY
CStdCSec FileCSec
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 987 of file C4Network2Res.cpp.

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

Referenced by C4Network2ResChunk::AddTo().

988 {
989  CStdLock FileLock(&FileCSec);
990  // FIXME: Use standard OC file access api here
991 #ifdef _WIN32
992  return _wopen(GetWideChar(szStandalone), _O_BINARY | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
993 #else
994  return open(szStandalone, _O_BINARY | O_CLOEXEC | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
995 #endif
996 }
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
#define O_CLOEXEC
char szStandalone[_MAX_PATH+1]
#define _O_BINARY
CStdCSec FileCSec
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 1139 of file C4Network2Res.cpp.

References _MAX_PATH, C4CFN_BigIcon, C4Group_CopyItem(), C4NetResMaxBigicon, C4Network2ResChunk::C4Network2ResChunk(), 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, szStandalone, and C4Network2ResChunk::~C4Network2ResChunk().

Referenced by GetStandalone().

1140 {
1141  CStdLock FileLock(&FileCSec);
1142  // for now: player files only
1143  if (Core.getType() == NRT_Player)
1144  {
1145  // log - this may take a few seconds
1146  if (!fSilent) LogF(LoadResStr("IDS_PRC_NETPREPARING"), GetFilename(szFile));
1147  // copy to temp file, if needed
1148  if (!fTempFile && SEqual(szFile, szStandalone))
1149  {
1150  char szNewStandalone[_MAX_PATH + 1];
1151  if (!pParent->FindTempResFileName(szStandalone, szNewStandalone))
1152  { if (!fSilent) Log("OptimizeStandalone: could not find free name for temporary file!"); return false; }
1153  if (!C4Group_CopyItem(szStandalone, szNewStandalone))
1154  { if (!fSilent) Log("OptimizeStandalone: could not copy to temporary file!"); return false; } /* TODO: Test failure */
1155  SCopy(szNewStandalone, szStandalone, sizeof(szStandalone) - 1);
1156  }
1157  // open as group
1158  C4Group Grp;
1159  if (!Grp.Open(szStandalone))
1160  { if (!fSilent) Log("OptimizeStandalone: could not open player file!"); return false; }
1161  // remove bigicon, if the file size is too large
1162  size_t iBigIconSize=0;
1163  if (Grp.FindEntry(C4CFN_BigIcon, nullptr, &iBigIconSize))
1164  if (iBigIconSize > C4NetResMaxBigicon*1024)
1165  Grp.Delete(C4CFN_BigIcon);
1166  Grp.Close();
1167  }
1168  return true;
1169 }
char * GetFilename(char *szPath)
Definition: StdFile.cpp:45
bool FindEntry(const char *szWildCard, StdStrBuf *sFileName=nullptr, size_t *iSize=nullptr)
Definition: C4Group.cpp:1774
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
C4Network2ResType getType() const
Definition: C4Network2Res.h:84
bool Delete(const char *szFiles, bool fRecursive=false)
Definition: C4Group.cpp:1334
#define _MAX_PATH
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
C4Network2ResCore Core
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
bool C4Group_CopyItem(const char *szSource, const char *szTarget1, bool fNoSort, bool fResetAttributes)
Definition: C4Group.cpp:100
bool Close()
Definition: C4Group.cpp:755
bool FindTempResFileName(const char *szFilename, char *pTarget)
char szStandalone[_MAX_PATH+1]
C4Network2ResList * pParent
#define C4CFN_BigIcon
Definition: C4Components.h:111
char szFile[_MAX_PATH+1]
bool Log(const char *szMessage)
Definition: C4Log.cpp:202
CStdCSec FileCSec
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:260
const int32_t C4NetResMaxBigicon
Definition: C4Network2Res.h:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Remove()

void C4Network2Res::Remove ( )

Definition at line 788 of file C4Network2Res.cpp.

References fRemoved.

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

789 {
790  // schedule for removal
791  fRemoved = true;
792 }
Here is the caller graph for this function:

◆ RemoveCChunks()

void C4Network2Res::RemoveCChunks ( ClientChunks pChunks)
protected

Definition at line 1122 of file C4Network2Res.cpp.

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

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

1123 {
1124  if (pChunks == pCChunks)
1125  pCChunks = pChunks->Next;
1126  else
1127  {
1128  // find previous entry
1129  ClientChunks *pPrev;
1130  for (pPrev = pCChunks; pPrev && pPrev->Next != pChunks; pPrev = pPrev->Next) {}
1131  // remove
1132  if (pPrev)
1133  pPrev->Next = pChunks->Next;
1134  }
1135  // delete
1136  delete pChunks;
1137 }
struct C4Network2Res::ClientChunks * pCChunks
Here is the caller graph for this function:

◆ RemoveLoad()

void C4Network2Res::RemoveLoad ( C4Network2ResLoad pLoad)
protected

Definition at line 1104 of file C4Network2Res.cpp.

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

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

1105 {
1106  if (pLoad == pLoads)
1107  pLoads = pLoad->Next();
1108  else
1109  {
1110  // find previous entry
1111  C4Network2ResLoad *pPrev;
1112  for (pPrev = pLoads; pPrev && pPrev->Next() != pLoad; pPrev = pPrev->Next()) {}
1113  // remove
1114  if (pPrev)
1115  pPrev->pNext = pLoad->Next();
1116  }
1117  // delete
1118  delete pLoad;
1119  iLoadCnt--;
1120 }
int32_t iLoadCnt
C4Network2ResLoad * pNext
C4Network2ResLoad * Next() const
C4Network2ResLoad * pLoads
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 811 of file C4Network2Res.cpp.

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().

812 {
813  assert(pParent && pParent->getIOClass());
814  if (!szStandalone[0] || iChunk >= Core.getChunkCnt()) return false;
815  // find connection for given client (one of the rare uses of the data connection)
817  if (!pConn) return false;
818  // save last request time
819  iLastReqTime = time(nullptr);
820  // create packet
821  CStdLock FileLock(&FileCSec);
822  C4Network2ResChunk ResChunk;
823  ResChunk.Set(this, iChunk);
824  // send
825  bool fSuccess = pConn->Send(MkC4NetIOPacket(PID_NetResData, ResChunk));
826  pConn->DelRef();
827  return fSuccess;
828 }
int32_t iLastReqTime
bool Send(const C4NetIOPacket &rPkt)
uint32_t getChunkCnt() const
Definition: C4Network2Res.h:96
C4Network2IO * getIOClass()
C4Network2ResCore Core
C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr=C4NetIO::addr_t())
Definition: C4PacketBase.h:40
bool Set(C4Network2Res *pRes, uint32_t iChunk)
char szStandalone[_MAX_PATH+1]
C4Network2ResList * pParent
C4Network2IOConnection * GetDataConnection(int iClientID)
CStdCSec FileCSec
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 794 of file C4Network2Res.cpp.

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

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

795 {
796  // pack status
798  // to one client?
799  if (pTo)
800  return pTo->Send(Pkt);
801  else
802  {
803  // reset dirty flag
804  fDirty = false;
805  // broadcast status
806  assert(pParent && pParent->getIOClass());
807  return pParent->getIOClass()->BroadcastMsg(Pkt);
808  }
809 }
bool Send(const C4NetIOPacket &rPkt)
C4Network2IO * getIOClass()
C4Network2ResCore Core
C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr=C4NetIO::addr_t())
Definition: C4PacketBase.h:40
bool BroadcastMsg(const C4NetIOPacket &rPkt)
C4Network2ResList * pParent
C4Network2ResChunkData Chunks
int32_t getID() const
Definition: C4Network2Res.h:86
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.

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

Referenced by C4Network2ResList::AddByCore().

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 }
char * GetFilename(char *szPath)
Definition: StdFile.cpp:45
int32_t MaxResSearchRecursion
Definition: C4Config.h:144
bool SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName=nullptr, bool fSilent=false)
C4Config Config
Definition: C4Config.cpp:833
char * GrabPointer()
Definition: StdBuf.h:459
void TruncateBackslash(char *szFilename)
Definition: StdFile.cpp:266
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
Definition: StdFile.cpp:855
C4ConfigGeneral General
Definition: C4Config.h:251
const char * GetC4Filename(const char *szPath)
Definition: StdFile.cpp:71
C4Network2ResType getType() const
Definition: C4Network2Res.h:84
uint32_t getContentsCRC() const
Definition: C4Network2Res.h:91
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
size_t SLen(const char *sptr)
Definition: Standard.h:74
bool SetByCore(const C4Network2ResCore &nCore, bool fSilent=false, const char *szAsFilename=nullptr, int32_t iRecursion=0)
C4Network2ResCore Core
void Take(char *pnData)
Definition: StdBuf.h:457
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
C4ConfigNetwork Network
Definition: C4Config.h:255
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:121
char WorkPath[CFG_MaxString+1]
Definition: C4Config.h:145
const char * getData() const
Definition: StdBuf.h:442
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:684
StdCopyStrBuf ExePath
Definition: C4Config.h:52
int32_t getID() const
Definition: C4Network2Res.h:86
#define DirectorySeparator
void Copy()
Definition: StdBuf.h:467
const char * getFileName() const
Definition: C4Network2Res.h:94
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.

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().

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 }
bool fStandaloneFailed
bool LocateItem(const char *filename, StdStrBuf &str) const
Definition: C4Reloc.cpp:93
int32_t iLastReqTime
C4Config Config
Definition: C4Config.cpp:833
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
bool GetFileCRC(const char *szFilename, uint32_t *pCRC32)
Definition: CStdFile.cpp:355
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:270
C4Network2ResCore Core
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)
const char * getData() const
Definition: StdBuf.h:442
C4Reloc Reloc
Definition: C4Reloc.cpp:21
char szFile[_MAX_PATH+1]
bool Open(C4Group &hGroup, const char *filename) const
Definition: C4Reloc.cpp:82
const char * AtRelativePath(const char *szFilename)
Definition: C4Config.cpp:656
CStdCSec FileCSec
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:260
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.

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().

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 }
bool fStandaloneFailed
int32_t iLastReqTime
C4Config Config
Definition: C4Config.cpp:833
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2078
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:270
C4Network2ResCore Core
void Set(C4Network2ResType eType, int32_t iResID, const char *strFileName, uint32_t iContentsCRC)
unsigned int EntryCRC32(const char *szWildCard=nullptr)
Definition: C4Group.cpp:1877
const char * getData() const
Definition: StdBuf.h:442
char szFile[_MAX_PATH+1]
const char * AtRelativePath(const char *szFilename)
Definition: C4Config.cpp:656
CStdCSec FileCSec
void Copy()
Definition: StdBuf.h:467
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.

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

Referenced by Derive().

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 }
bool fStandaloneFailed
int32_t iLastReqTime
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
#define _MAX_PATH
const int32_t C4NetResIDAnonymous
Definition: C4Network2Res.h:38
C4Network2ResCore Core
void Set(C4Network2ResType eType, int32_t iResID, const char *strFileName, uint32_t iContentsCRC)
void SetDerived(int32_t inDerID)
char szStandalone[_MAX_PATH+1]
char szFile[_MAX_PATH+1]
CStdCSec FileCSec
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.

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().

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 }
bool fStandaloneFailed
int32_t iLastReqTime
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
bool ThreadLogS(const char *szMessage,...) GNUC_FORMAT_ATTRIBUTE_O
uint32_t getChunkCnt() const
Definition: C4Network2Res.h:96
time_t iDiscoverStartTime
C4Network2ResCore Core
bool FindTempResFileName(const char *szFilename, char *pTarget)
char szStandalone[_MAX_PATH+1]
C4Network2ResList * pParent
bool isLoadable() const
Definition: C4Network2Res.h:88
char szFile[_MAX_PATH+1]
C4Network2ResChunkData Chunks
int32_t getID() const
Definition: C4Network2Res.h:86
void SetIncomplete(int32_t iChunkCnt)
CStdCSec FileCSec
C4Application Application
Definition: C4Globals.cpp:44
C4InteractiveThread InteractiveThread
Definition: C4Application.h:45
const char * getFileName() const
Definition: C4Network2Res.h:94
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 1045 of file C4Network2Res.cpp.

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().

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

◆ StartNewLoads()

void C4Network2Res::StartNewLoads ( )
protected

Definition at line 998 of file C4Network2Res.cpp.

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

Referenced by DoLoad(), and OnChunk().

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

Definition at line 223 of file C4Network2Res.h.

Referenced by OnDiscover(), SendChunk(), SetByFile(), SetByGroup(), SetDerived(), and SetLoad().

◆ 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: