port 2V2-d.1: ActorInstance/InstanceBase closure creates the main character

Port the ActorInstance*/InstanceBase* siblings plus GameUtil, FlyTarget,
PhysicsObject, GameEventManager, WeaponTrace, MapUtil and lineintersect_utils
verbatim and drop their pending stand-ins; CGameEventManager and CPythonSystem
join PythonBoot in CPythonApplication member order.

Root cause of the intermittent Loading-phase header 7: TPlayerSkill::tNextRead
is time_t, 32-bit in 40250 (_USE_32BIT_TIME_T) but 64-bit on LP64, so
SKILL_LEVEL (76) was read as 2551 bytes instead of 1531. Packet.h now uses
LONG with a static_assert, and the fake server sends SKILL_LEVEL in Loading.

The fake server's CHARACTER_ADD now uses CHAR_TYPE_PC; port.login_flow
asserts the main instance exists with race 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 19:02:21 +09:00
co-authored by Claude Opus 5.5
parent 996d793f0c
commit 5266b00c6e
71 changed files with 13832 additions and 1405 deletions
+6 -3
View File
@@ -404,7 +404,8 @@ bool FakeLoginServer::ServeGame(Connection& c, int index)
return Fail(name + ": CG_CHARACTER_SELECT picks an empty slot");
Event(name + ":select");
// CInputDB::PlayerLoad: SetPhase(PHASE_LOADING), CHARACTER::MainCharacterPacket, PointsPacket.
// CInputDB::PlayerLoad: SetPhase(PHASE_LOADING), CHARACTER::MainCharacterPacket, PointsPacket,
// SkillLevelPacket (1531 bytes; guards the client's 32-bit time_t TPlayerSkill layout).
auto main = zeroed<GCMainCharacter>();
main.header = HDR_GC_MAIN_CHARACTER;
main.vid = kMainVID;
@@ -416,7 +417,9 @@ bool FakeLoginServer::ServeGame(Connection& c, int index)
auto points = zeroed<GCPoints>();
points.header = HDR_GC_CHARACTER_POINTS;
points.points[1] = 10; // POINT_LEVEL
if (!c.Phase(PHASE_LOADING) || !c.Send(main) || !c.Send(points))
auto skill = zeroed<GCSkillLevel>();
skill.header = HDR_GC_SKILL_LEVEL;
if (!c.Phase(PHASE_LOADING) || !c.Send(main) || !c.Send(points) || !c.Send(skill))
return Fail(name + ": send loading packets");
// The client answers the main character with its version (CInputProcessor::Version).
@@ -448,7 +451,7 @@ bool FakeLoginServer::ServeGame(Connection& c, int index)
actor.vid = kMainVID;
actor.x = kX;
actor.y = kY;
actor.type = 0; // CHAR_TYPE_PC
actor.type = 6; // CHAR_TYPE_PC (common/length.h ECharType)
actor.race = 0; // warrior male
actor.moving_speed = 100;
actor.attack_speed = 100;