CD Code Digest Hub /CS:GO

概览:这个仓库是什么

12 分钟阅读 7 个章节 1 张图

本页给出整个代码库的“地图”:它包含哪些可部署单元、它们如何在运行时组合、一个玩家在服务器上开一枪时代码会穿过哪些模块,以及这份快照缺了什么。后续各页按子系统展开。

阅读前提:本文所有结论都基于仓库快照 f82112a2388b841d72cb62ca48ab1846dfcc11c8(提交日期 2020-04-23)的静态阅读,没有编译或运行。

1. 一句话定位#

这是 Valve Source 引擎(CS:GO 分支)+ CS:GO 游戏模块 + 配套内容工具的 C++ 源码树,构建由 Valve 自有的 VPC 工程生成器驱动,默认工程组是 csgo_partner:CreateSolution.bat:1、vpc_scripts/default.vgc:11-24。

它不是可直接运行的游戏发行包:仓库中找不到任何 .bsp/.vpk/.mdl/.vtf/.vmt 内容文件(本次用文件扫描确认为 0 个),根目录的提示文本也要求另行下载 2017-05-18 的游戏文件:[CSGO NEEDS MAY 18 2017 FILES BEFORE HYDRA.txt](../Counter-Strike-Global-Offensive/CSGO NEEDS MAY 18 2017 FILES BEFORE HYDRA.txt)。

2. 仓库形态#

维度观察证据
规模git ls-files 共 14,245 个文件;game/ 2,744、thirdparty/ 2,634、materialsystem/ 1,733、public/ 1,717、engine/ 741本次统计命令(见 审计)
游戏VPC 只启用 CSGO 一个游戏,其余游戏(TF、Portal2、DOTA…)被注释vpc_scripts/default.vgc:11-21
平台工程条件同时出现 Windows、POSIX/Linux、OSX、X360、PS3vpc_scripts/projects.vgc:185、vpc_scripts/projects.vgc:1243
构建没有统一 CMake;vpc.exe 生成 .sln,.proto 通过自定义构建步骤调用仓库内 protoc.exeCreateSolution.bat:1、vpc_scripts/protobuf_builder.vpc:9-19
测试unittests/ 只有 1 个跟踪文件,而工程注册表登记了多个测试工程vpc_scripts/projects.vgc:1626-1634、unittests/rendersystemtest/worldrenderertest.cpp

3. 运行时组件关系#

图中每条边的证据:

  • csgo.exe 入口加载 bin\launcher.dll 并调用导出函数 LauncherMain:launcher_main/main.cpp:151-176。
  • LauncherMain 用 CSteamApplication 包裹 CSourceAppSystemGroup 并运行:launcher/launcher.cpp:1870-1881;CSteamApplication::Create 先加载 cvar 与文件系统模块:appframework/WinApp.cpp:148-171。
  • CSourceAppSystemGroup::Create 的模块清单包含 engine、filesystem_stdio、inputsystem、vphysics、materialsystem、datacache、studiorender、soundemittersystem、vscript 等:launcher/launcher.cpp:727-770。
  • 引擎在 CModAppSystemGroup::Create 中加载 matchmaking(专用服务器为 matchmaking_ds)、client 与 server 模块:engine/sys_dll2.cpp:2190-2259。
  • 专用服务器入口加载 bin\dedicated.dll 并调用 DedicatedMain:dedicated_main/main.cpp:98-113,后者通过 VENGINE_HLDS_API_VERSION 获取引擎的专用服务器接口:dedicated/sys_windows.cpp:266-289。

模块之间几乎全部通过“版本化接口名 + CreateInterface 工厂”连接,而不是直接链接导出符号;这是理解整个代码库的第一把钥匙,见 接口工厂与 AppSystem。

4. 一次射击如何穿过各层(代表性端到端路径)#

  1. 客户端引擎在每个 tick 的输入阶段调用 CL_Move,再由 client.dll 的 CInput::CreateMove 生成 CUserCmd:engine/host.cpp:3278-3290、game/client/in_main.cpp:1350-1361。
  2. 命令被增量编码进 CCLCMsg_Move 发往服务器:engine/cl_main.cpp:2684-2731。
  3. 服务器引擎收到 clc_Move 后交给 IServerGameClients::ProcessUsercmds,玩家在随后的 GameFrame 物理模拟中执行命令:engine/sv_client.cpp:253-305、game/server/player.cpp:3598-3611。
  4. 武器的 PrimaryAttack → CSBaseGunFire → 共享函数 FX_FireBullets,服务端在其中包裹延迟补偿并逐弹调用 CCSPlayer::FireBullet:game/shared/cstrike15/weapon_csbasegun.cpp:305-337、game/shared/cstrike15/fx_cs_shared.cpp:380-383、game/shared/cstrike15/fx_cs_shared.cpp:548-577。
  5. 伤害改变网络变量(如血量、金钱),帧末 SV_SendClientUpdates 打快照、按客户端 PVS 差量编码实体并发送:engine/sv_main.cpp:3402-3417、engine/sv_main.cpp:2213-2263。
  6. 客户端 CL_ProcessPacketEntities 解码实体,HUD 在下一帧读取新值(例如金钱面板读 GetAccount()):engine/cl_ents_parse.cpp:574-701、game/client/cstrike15/Scaleform/HUD/sfhudmoney.cpp:194-227。

各步骤的细节分别在 输入与预测、武器与射击、延迟补偿、实体复制、HUD 页面。

5. 关键设计约束(贯穿全书)#

  • 同一份源码编译两次。 game/shared 下的规则、移动、武器文件同时出现在 client 与 server 工程里,分别用 CLIENT_DLL / GAME_DLL 宏区分分支:game/client/client_cstrike15.vpc:175-181、game/server/server_cstrike15_inc.vpc:96-110、game/client/client_base.vpc:60、game/server/server_base.vpc:56。阅读这些文件时必须先确认当前分支属于哪一端。
  • 服务器权威、客户端预测。 服务器真正执行 CUserCmd;客户端用同一套移动/武器代码先行模拟并在收到权威状态后重放,见 输入与预测。
  • 固定 tick。 引擎把可变的帧时间累积并切成整数个 interval_per_tick,每个 tick 依次跑输入、服务器、客户端:engine/host.cpp:4079-4096、engine/host.cpp:4185-4277。
  • 输出不在仓库内。 引擎与工具输出到 $SRCDIR\..\game\bin,游戏 DLL 输出到 $SRCDIR\..\game\csgo\bin:engine/engine_inc.vpc:8、game/client/client_base.vpc:8。

6. 完整性边界(重要)#

缺口证据影响
vphysics 实现源码不存在,但启动器与专用服务器都要加载 vphysics 模块vpc_scripts/projects.vgc:1956-1959、launcher/launcher.cpp:739、dedicated/sys_windows.cpp:274只能依赖外部二进制;lib/common 下有 IVP/Havana 预编译库
Scaleform SDK(thirdparty/scaleform/sdk42)不存在,但 scaleformui 工程引用它scaleformui/scaleformui.vpc:33-51HUD/菜单接入层源码在,SDK 不在
服务端调用 GCClientSystem(),但全仓库没有任何头文件声明它;多个客户端文件 include 的 gc_clientsystem.h 也不存在game/server/gameinterface.cpp:1397-1405、game/server/cstrike15/cs_voteissues.cpp:22-24不定义 NO_STEAM_GAMECOORDINATOR 时服务端很可能无法编译(推断)
44 个源文件中共有 131 处 Removed for partner depot 标记,函数体或分支被删空,例如武器后坐力 CWeaponCSBase::Recoilgame/shared/cstrike15/weapon_csbase.cpp:3833-3836、game/server/cstrike15/cs_gameinterface.cpp:149-165部分玩法、GC、反作弊/认证、UI 行为在源码层面不完整
GC 后端、gcsdk_game.vpc 不存在,仅有接口与预编译 gcsdk.libvpc_scripts/projects.vgc:445-453只能看到协议与客户端接入
无内容资源、几乎无测试见上文不能把“源码覆盖面”当作“可重建程度”

详细清单与证据状态见 构建与物理组织 和 审计。

7. 推荐阅读路线#

  1. 构建与物理组织:先确定哪些目录真正参与 csgo_partner 构建。
  2. 接口工厂与 AppSystem → 客户端启动链:理解模块如何被装配。
  3. 主循环与 Tick → 网络通道与协议 → 实体复制:引擎核心。
  4. 游戏 DLL 契约 → CS:GO 玩法总览:玩法层。
  5. 按需进入 渲染、音频、输入与命令、服务器运维面、资源与缓存、内容工具链。