port 2A step 4: platform skeleton + rest of the 2V3 header closure

- Mirror the remaining non-Python 2V3 closure headers (98 more, 173 total): EffectLib,
  EterGrnLib, SpeedTreeLib, SphereLib, PRTerrainLib, EterImageLib, EterBase/Poly, cipher/tea,
  EterLib Grp*/IME/Input/MSWindow/StateManager, GameLib actor/map/race headers, EterPack.
- SDK shims: granny.h, SpeedTreeRT.h, imm.h, Dimm.h (the SDK MIDL header, not mirrored),
  dinput/d3dx8 additions; D3D8 render-state enums, FVF macros and the COM resource hierarchy;
  more Win32 GDI/handle types with layout static_asserts.
- PORT edits for MSVC-permissive code (typename, friend visibility, <algorithm>, pointer→uintptr_t)
  and PRTerrainLib/StdAfx.h dropping the ScriptLib/Python include.
- port_logic links the vendored cryptopp/minilzo.
- extension/src/platform: port_platform target with 103 generated stub files (1917 function
  stubs, 146 static members) from the new platform_stub.py (clang -ast-dump-filter);
  MT_PLATFORM_STUB() marks every unimplemented body. libmtgodot links port_platform and
  port_gate.sh builds it.

Gate: macOS, Android, iOS, Windows (mingw) PASS; Linux BLOCKED (no toolchain).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-22 21:46:24 +09:00
co-authored by Claude Opus 5
parent fc47582017
commit 9a8e11f3dd
220 changed files with 24287 additions and 25 deletions
+248
View File
@@ -0,0 +1,248 @@
#ifndef __INC_ETERPACKLIB_ETERPACK_H__
#define __INC_ETERPACKLIB_ETERPACK_H__
#include <list>
#include <unordered_map>
#include "../EterBase/MappedFile.h"
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \
((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24))
#endif
//#define CHECKSUM_CHECK_MD5
#include "md5.h"
namespace eterpack
{
const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D');
const DWORD c_IndexCC = MAKEFOURCC('E', 'P', 'K', 'D');
const DWORD c_Version = 2;
// FourCC + Version + m_indexCount
const DWORD c_HeaderSize = sizeof(DWORD) + sizeof(DWORD) + sizeof(long);
};
enum EEterPackTypes
{
DBNAME_MAX_LEN = 255,
FILENAME_MAX_LEN = 160,
FREE_INDEX_BLOCK_SIZE = 32768,
FREE_INDEX_MAX_SIZE = 512,
DATA_BLOCK_SIZE = 256,
COMPRESSED_TYPE_NONE = 0,
COMPRESSED_TYPE_COMPRESS = 1,
COMPRESSED_TYPE_SECURITY = 2,
COMPRESSED_TYPE_PANAMA = 3,
COMPRESSED_TYPE_HYBRIDCRYPT = 4,
COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB = 5,
COMPRESSED_TYPE_COUNT = 6,
};
#pragma pack(push, 4)
typedef struct SEterPackIndex
{
long id;
char filename[FILENAME_MAX_LEN + 1];
DWORD filename_crc;
long real_data_size;
long data_size;
#ifdef CHECKSUM_CHECK_MD5
BYTE MD5Digest[16];
#else
DWORD data_crc;
#endif
long data_position;
char compressed_type;
} TEterPackIndex;
#pragma pack(pop)
typedef std::unordered_map<DWORD, TEterPackIndex *> TDataPositionMap;
typedef std::list<TEterPackIndex *> TFreeIndexList;
class CEterPack;
class CEterFileDict
{
public:
struct Item
{
Item() : pkPack(NULL), pkInfo(NULL) {}
CEterPack* pkPack;
TEterPackIndex* pkInfo;
};
enum
{
BUCKET_SIZE = 16,
};
typedef std::unordered_multimap<DWORD, Item> TDict;
public:
void InsertItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
void UpdateItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
Item* GetItem(DWORD dwFileNameHash, const char* c_pszFileName);
const TDict& GetDict() const
{
return m_dict;
}
private:
TDict m_dict;
};
class EterPackPolicy_CSHybridCrypt;
class CEterPack
{
public:
CEterPack();
virtual ~CEterPack();
void Destroy();
bool Create(CEterFileDict& rkFileDict, const char * dbname, const char * pathName, bool bReadOnly = true, const BYTE* iv = NULL);
bool DecryptIV(DWORD dwPanamaKey);
const std::string& GetPathName();
const char * GetDBName();
//THEMIDA
bool Get(CMappedFile & mappedFile, const char * filename, LPCVOID * data);
//THEMIDA
bool Get2(CMappedFile & mappedFile, const char * filename, TEterPackIndex* index, LPCVOID * data);
//THEMIDA
bool Put(const char * filename, const char * sourceFilename, BYTE packType, const std::string& strRelateMapName);
//THEMIDA
bool Put(const char * filename, LPCVOID data, long len, BYTE packType);
bool Delete(const char * filename);
bool Extract();
long GetFragmentSize();
bool IsExist(const char * filename);
TDataPositionMap & GetIndexMap();
bool EncryptIndexFile();
bool DecryptIndexFile();
DWORD DeleteUnreferencedData(); // 몇개가 삭제 되었는지 리턴 한다.
bool GetNames(std::vector<std::string>* retNames);
EterPackPolicy_CSHybridCrypt* GetPackPolicy_HybridCrypt() const;
private:
bool __BuildIndex(CEterFileDict& rkFileDict, bool bOverwirte=false);
bool CreateIndexFile();
TEterPackIndex * FindIndex(const char * filename);
long GetNewIndexPosition(CFileBase& file);
TEterPackIndex * NewIndex(CFileBase& file, const char * filename, long size);
void WriteIndex(CFileBase& file, TEterPackIndex * index);
int GetFreeBlockIndex(long size);
void PushFreeIndex(TEterPackIndex * index);
bool CreateDataFile();
long GetNewDataPosition(CFileBase& file);
bool ReadData(CFileBase& file, TEterPackIndex * index, LPVOID data, long maxsize);
bool WriteData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
bool WriteNewData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
bool Delete(TEterPackIndex * pIndex);
protected:
CMappedFile m_file;
char* m_file_data;
unsigned m_file_size;
long m_indexCount;
bool m_bEncrypted;
char m_dbName[DBNAME_MAX_LEN+1];
char m_indexFileName[MAX_PATH+1];
TEterPackIndex * m_indexData;
long m_FragmentSize;
bool m_bReadOnly;
bool m_bDecrypedIV;
std::unordered_map<DWORD, DWORD> m_map_indexRefCount;
TDataPositionMap m_DataPositionMap;
TFreeIndexList m_FreeIndexList[FREE_INDEX_MAX_SIZE + 1]; // MAX 도 억세스 하므로 + 1 크기만큼 만든다.
std::string m_stDataFileName;
std::string m_stPathName;
EterPackPolicy_CSHybridCrypt* m_pCSHybridCryptPolicy;
private:
void __CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize);
bool __Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
bool __Encrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
std::string m_stIV_Panama;
//private:
// bool m_bIsDataLoaded;
// // 그냥 time_t를 쓰면, 32bit time_t를 사용하는 소스에서는,
// // CEterPack의 size를 실제 size - 4로 인식하기 때문에 문제가 발생할 수 있다.
// __time64_t m_tLastAccessTime;
//public:
// __time64_t GetLastAccessTime() { return m_tLastAccessTime; }
// void UpdateLastAccessTime();
// void ClearDataMemoryMap();
#ifdef CHECKSUM_CHECK_MD5
void GenerateMD5Hash( BYTE* pData, int nLength, IN OUT MD5_CTX& context );
#endif
};
class CMakePackLog
{
public:
static CMakePackLog& GetSingleton();
public:
CMakePackLog();
~CMakePackLog();
void SetFileName(const char* c_szFileName);
void Writef(const char* c_szFormat, ...);
void Writenf(const char* c_szFormat, ...);
void Write(const char* c_szBuf);
void WriteErrorf(const char* c_szFormat, ...);
void WriteErrornf(const char* c_szFormat, ...);
void WriteError(const char* c_szBuf);
void FlushError();
private:
void __Write(const char* c_szBuf, int nBufLen);
void __WriteError(const char* c_szBuf, int nBufLen);
bool __IsLogMode();
private:
FILE* m_fp;
FILE* m_fp_err;
std::string m_stFileName;
std::string m_stErrorFileName;
};
#endif
@@ -0,0 +1,96 @@
#pragma once
#include <windows.h>
#include <unordered_map>
#include "../EterBase/Singleton.h"
#include "../EterBase/Stl.h"
#include "EterPack.h"
class CEterPackManager : public CSingleton<CEterPackManager>
{
public:
struct SCache
{
BYTE* m_abBufData;
DWORD m_dwBufSize;
};
public:
enum ESearchModes
{
SEARCH_FILE_FIRST,
SEARCH_PACK_FIRST
};
typedef std::list<CEterPack*> TEterPackList;
typedef std::unordered_map<std::string, CEterPack*, stringhash> TEterPackMap;
public:
CEterPackManager();
virtual ~CEterPackManager();
void SetCacheMode();
void SetRelativePathMode();
void LoadStaticCache(const char* c_szFileName);
void SetSearchMode(bool bPackFirst);
int GetSearchMode();
//THEMIDA
bool Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData);
//THEMIDA
bool GetFromPack(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData);
//THEMIDA
bool GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData);
bool isExist(const char * c_szFileName);
bool isExistInPack(const char * c_szFileName);
bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL);
void RegisterRootPack(const char * c_szName);
bool RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack);
bool DecryptPackIV(DWORD key);
const char * GetRootPackFileName();
//for hybridcrypt
//THEMIDA
void WriteHybridCryptPackInfo(const char* pFileName);
//THEMIDA
void RetrieveHybridCryptPackKeys( const BYTE* pStream );
//THEMIDA
void RetrieveHybridCryptPackSDB( const BYTE* pStream );
// 메모리에 매핑된 팩들 가운데, 정리해야할 것들 정리.
public:
void ArrangeMemoryMappedPack();
protected:
int ConvertFileName(const char * c_szFileName, std::string & rstrFileName); // StringPath std::string 버전
bool CompareName(const char * c_szDirectoryName, DWORD iLength, const char * c_szFileName);
CEterPack* FindPack(const char* c_szPathName);
SCache* __FindCache(DWORD dwFileNameHash);
void __ClearCacheMap();
protected:
bool m_bTryRelativePath;
bool m_isCacheMode;
int m_iSearchMode;
CEterFileDict m_FileDict;
CEterPack m_RootPack;
TEterPackList m_PackList;
TEterPackMap m_PackMap;
TEterPackMap m_DirPackMap;
std::unordered_map<DWORD, SCache> m_kMap_dwNameKey_kCache;
CRITICAL_SECTION m_csFinder;
};