port(2P step 3a/3b): stdlib on sys.path + the pack module
step 3a — 标准库: tools/py_embed/make_stdlib_zip.py packs the vendored Lib/ into <build>/python27.zip (397 modules, 6876547 bytes, ZIP_STORED — the zlib module is trimmed out of our CPython, so zipimport cannot inflate). The mtpython_stdlib target builds it; py_embed_test and the launcher test both run against it. platform/ScriptLib/PythonHost sets the embedding flags before Py_Initialize and, after it, puts the zip on sys.path and re-registers encodings.search_function with codecs — 2.7 builds the codec registry once, at startup, so replacing sys.path afterwards needs it back. step 3b — pack 模块: UserInterface/PythonPackModule.cpp copied verbatim; packExist/packGet/ initpack read root/ and uiscript/ through CEterPackManager, i.e. through asset_io. The CHINA_CRYPT_KEY block in that unit is CAccountConnector's and is kept #if 0 until the login slice (2V1). UserInterface/StdAfx.h is a documented partial mirror — the original is the whole client's PCH. The launcher test now runs initpack() as RunMainScript does (its first line), reads system.py / uiscript / locale text back out of the packs, and confirms cp1252 decoding works off the zip. system.py still stops at "No module named app" — the C++ modules are the 2V0 slice. gates: port_map.py check 0 errors · key leak check 8/8 none · macOS ctest 27/27 · android + ios port_platform compile clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -164,8 +164,9 @@ if(BUILD_TESTING AND CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME)
|
||||
if(TARGET mtpython)
|
||||
add_executable(port_python_launcher_test ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/port_python_launcher_test.cpp)
|
||||
target_link_libraries(port_python_launcher_test PRIVATE port_platform)
|
||||
add_dependencies(port_python_launcher_test mtpython_stdlib)
|
||||
add_test(NAME port.python_launcher
|
||||
COMMAND $<TARGET_FILE:port_python_launcher_test> ${MT_40250_CLIENT})
|
||||
COMMAND $<TARGET_FILE:port_python_launcher_test> ${MT_40250_CLIENT} ${MT_PYTHON_STDLIB_ZIP})
|
||||
set_tests_properties(port.python_launcher PROPERTIES SKIP_RETURN_CODE 77)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
#include "../EterBase/tea.h"
|
||||
|
||||
// CHINA_CRYPT_KEY
|
||||
DWORD g_adwEncryptKey[4];
|
||||
DWORD g_adwDecryptKey[4];
|
||||
|
||||
// PORT: the login cipher's key builder happens to live in this unit, but it is CAccountConnector's —
|
||||
// AccountConnector.h and the class come with the login slice (docs/PORT-PLAN.md 批次 2V1). Kept verbatim
|
||||
// and compiled out until then; the two keys above stay, they are what the network stream reads.
|
||||
#if 0
|
||||
#include "AccountConnector.h"
|
||||
|
||||
inline const BYTE* GetKey_20050304Myevan()
|
||||
{
|
||||
volatile static DWORD s_adwKey[1938];
|
||||
|
||||
volatile DWORD seed=1491971513;
|
||||
for (UINT i=0; i<BYTE(seed); i++)
|
||||
{
|
||||
seed^=2148941891;
|
||||
seed+=3592385981;
|
||||
s_adwKey[i]=seed;
|
||||
}
|
||||
|
||||
return (const BYTE*)s_adwKey;
|
||||
}
|
||||
|
||||
//#include <eterCrypt.h>
|
||||
|
||||
void CAccountConnector::__BuildClientKey_20050304Myevan()
|
||||
{
|
||||
const BYTE * c_pszKey = GetKey_20050304Myevan();
|
||||
memcpy(g_adwEncryptKey, c_pszKey+157, 16);
|
||||
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
g_adwEncryptKey[i] = random();
|
||||
|
||||
tea_encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16);
|
||||
// TEA_Encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16);
|
||||
}
|
||||
#endif
|
||||
// END_OF_CHINA_CRYPT_KEY
|
||||
|
||||
PyObject * packExist(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
char * strFileName;
|
||||
|
||||
if (!PyTuple_GetString(poArgs, 0, &strFileName))
|
||||
return Py_BuildException();
|
||||
|
||||
return Py_BuildValue("i", CEterPackManager::Instance().isExist(strFileName)?1:0);
|
||||
}
|
||||
|
||||
PyObject * packGet(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
char * strFileName;
|
||||
|
||||
if (!PyTuple_GetString(poArgs, 0, &strFileName))
|
||||
return Py_BuildException();
|
||||
|
||||
// 파이썬에서 읽어드리는 패킹 파일은 python 파일과 txt 파일에 한정한다
|
||||
const char* pcExt = strrchr(strFileName, '.');
|
||||
if (pcExt) // 확장자가 있고
|
||||
{
|
||||
if ((stricmp(pcExt, ".py") == 0) ||
|
||||
(stricmp(pcExt, ".pyc") == 0) ||
|
||||
(stricmp(pcExt, ".txt") == 0))
|
||||
{
|
||||
CMappedFile file;
|
||||
const void * pData = NULL;
|
||||
|
||||
if (CEterPackManager::Instance().Get(file,strFileName,&pData))
|
||||
return Py_BuildValue("s#",pData, file.Size());
|
||||
}
|
||||
}
|
||||
|
||||
return Py_BuildException();
|
||||
}
|
||||
|
||||
void initpack()
|
||||
{
|
||||
static PyMethodDef s_methods[] =
|
||||
{
|
||||
{ "Exist", packExist, METH_VARARGS },
|
||||
{ "Get", packGet, METH_VARARGS },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
Py_InitModule("pack", s_methods);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
// PORT: a partial mirror of 40250 UserInterface/StdAfx.h.
|
||||
//
|
||||
// The original is the precompiled header of the whole client: it includes eterLib, eterPythonLib,
|
||||
// gameLib, scriptLib, milesLib, EffectLib, PRTerrainLib and SpeedTreeLib's StdAfx.h, plus <dshow.h>
|
||||
// and <qedit.h>, Locale.h and GameType.h. Only scriptLib exists in the port tree today, so this file
|
||||
// carries the part the ported units actually use and grows with the 2V slices that bring the rest
|
||||
// (docs/PORT-PLAN.md 批次 2V0-2V3).
|
||||
|
||||
#include "../ScriptLib/StdAfx.h"
|
||||
|
||||
#define APP_NAME "Metin 2"
|
||||
|
||||
enum
|
||||
{
|
||||
POINT_MAX_NUM = 255,
|
||||
CHARACTER_NAME_MAX_LEN = 24,
|
||||
#if defined(LOCALE_SERVICE_JAPAN)
|
||||
PLAYER_NAME_MAX_LEN = 16,
|
||||
#else
|
||||
PLAYER_NAME_MAX_LEN = 12,
|
||||
#endif
|
||||
};
|
||||
|
||||
// The Python module initializers RunMainScript calls, each defined in its own Python*Module.cpp.
|
||||
// Listed here as 40250 lists them; only the ported ones are defined.
|
||||
void initpack();
|
||||
Reference in New Issue
Block a user