MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

《植物大战僵尸》线上对战工程深度技术分析

项目背景与痛点

「植物大战僵尸」作为一款经典的塔防游戏,一直以其独特的玩法和精彩的游戏体验吸引着无数玩家。然而,游戏本身并不支持多人在线对战,这限制了玩家之间的实时互动和竞技体验。Zhuagenborn/Plants-vs.-Zombies-Online-Battle 项目的诞生,正是为了填补这一空白。通过逆向工程、内联 Hook 和动态链接库注入技术,开发者为游戏引入了双人在线对战模式,用户可以在网络环境中进行实时对抗,作为植物或僵尸进行防守和攻击。

为什么我们需要它?这种双人在线对战模式不仅丰富了玩家的游戏体验,而且创造了一个全新的竞争力场域,增强了玩家间的互动性和游戏可玩性,极大地满足了玩家对于即时多人对战的需求。

核心技术揭秘

技术架构与实现原理

项目的核心在于通过逆向工程解析游戏的执行流程,并在关键位置插入内联Hook,利用动态链接库注入技术在运行时动态修改游戏逻辑,从而实现在线对战功能。以下为项目主要的技术架构:

逆向工程:对游戏二进制文件进行逆向分析,定位关键的数据结构和函数调用。 内联Hook:在游戏逻辑的关键点插入Hook函数,实现逻辑的动态修改。 动态链接库注入:通过外部的DLL注入,管理玩家状态,并处理网络通信。

graph TD A[客户端启动] --> B[加载游戏进程] B --> C[注入动态库] C --> D[Hook游戏逻辑] D --> E[执行Hook函数逻辑] E --> F[发送和接收网络数据] F --> G{"判断网络状态"} G -->|"正常数据流"| H[更新玩家状态] G -->|"异常数据流"| I[执行错误处理] H --> J{"玩家操作检测"} J -->|"战斗操作"| K[处理防御或攻击逻辑] J -->|"其他操作"| L[处理其他逻辑]

核心技术栈与设计模式

该项目使用了逆向工程及底层编程技术,揭示了工程师对于游戏底层逻辑的深入理解与掌控。尤其在处理跨平台网络通信与实时状态同步上,创新性地结合内联Hook技术与动态链接库注入,为两者提供无缝的交互支持,从而保障在线对战体验与性能。

功能亮点与差异

相较于其他仅通过修改游戏代码或利用现有功能的小幅调整而实现的在线模式的项目,Zhuagenborn/Plants-vs.-Zombies-Online-Battle 的最大差异化在于其开创性的跨平台在线对战功能。通过深度解析与修改游戏底层逻辑,实现了平滑且实时的网络通讯与状态同步。这种技术深度和对原有游戏逻辑的拓展,让玩家体验到区别于普通单人或线下模式的游戏体验,不仅增强了互动乐趣,也为开发者提供了可复制和再创新的框架。

应用场景与落地建议

在实际应用中,用户需要确保稳定的网络环境以提供流畅的游戏体验。开发者建议在高性能的服务器上部署项目,以获得更好的对战表现。此外,这一项目特别适用于游戏开发与逆向工程相关的课程教学、实际项目开发,以及希望在现有游戏的基础上添加实时竞技元素的情形。

综合评价

项目无疑展示了高超的逆向工程能力和对复杂系统的技术创新。然而,它也展现出一些挑战。例如,对于框架和工具的依赖可能提高入门和维护成本;长期维护可能需要追踪游戏版本更新,同步修复兼容性问题;且逆向工程的方法并不总是“绿色”的法律途径,因此需注意合规性风险。

综上所述,该项目以其技术深度将「植物大战僵尸 」在线化,为玩家和开发社区带来了全新的可能性。

关于

GitHub 原始描述(英文)

🧟 Plants vs. Zombies multiplayer battle, developed via reverse engineering, inline hook and dynamic-link library injection. Two online players defend and attack as the plant and zombie respectively(通过逆向工程、内联Hook和动态链接库注入实现的《植物大战僵尸》双人网络对战,两名玩家分别使用植物或僵尸进行防守和攻击)

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
751
价值分
394
活跃状态
活跃

语言占比

C++
CMake
PowerShell

Release

贡献者

README

Plants vs. Zombies Online Battle

C++ MASM CMake Visual-Studio Windows License

Introduction

Cover

This project adds the multiplayer battle to Plants vs. Zombies via reverse engineering, inline hook and dynamic-link library injection. Two online players can defend and attack as Plant and Zombie respectively.

Getting Started

Prerequisites

Building

Set the location to the project folder and run:

mkdir -p build
cd build
cmake .. -G "Visual Studio 17 2022" -A Win32
cmake --build .

Two dynamic-link libraries plant.dll and zombie.dll will be generated in build/bin folder. Copy them to the game root folder.

IPv6

The default IP version is IPv4. Enable the following statement in libs/game/CMakeLists.txt if you want to build IPv6 libraries.

target_compile_definitions(game PRIVATE INET6=1)

Usage

The project only works with Plants vs. Zombies 1.0.0.1051 CHINESE version, provided in game folder.

The MD5 of PlantsVsZombies.exe is 37B729B4056131722A556E646AC915E9.

In order to activate online functions, plant.dll and zombie.dll must be injected into the game when it starts. You can directly use this simple injection tool: Dll-Injector.

online-battle

Playing as Plant

If a player plays as the plant, the game will launch as a server.

Dll-Injector -f PlantsVsZombies.exe plant.dll

Or use Start-OnlineGame.ps1 directly. It needs to be copied to the game root folder.

Start-OnlineGame.ps1 -Role Plant

Start I, Zombie Endless level, the game will pause and wait for a client to connect.

Playing as Zombie

If a player plays as the zombie, the game will launch as a client.

Dll-Injector -f PlantsVsZombies.exe zombie.dll

Or use Start-OnlineGame.ps1.

Start-OnlineGame.ps1 -Role Zombie

Start I, Zombie Endless level, the game will try to connect to the server.

I, Zombie Endless

If the modification has been loaded successfully, I, Zombie Endless level will be converted into an online level. If your current progress does not have this level, you can copy game/userdata to C:\ProgramData\PopCap Games\PlantsVsZombies\userdata. Remember to back up your own save-files before copying.

In the Chinese version of the game, you can start this level as follows:

  1. Select “解谜模式”, which means “Puzzle” in English.

    puzzle-mode

  2. Select “我是僵尸无尽版”, the final level. It is “I, Zombie Endless” in English.

    i-zombie-endless

  3. The game will display a dialog box shown as below. Select “继续”, the left button, meaning “Continue” in English.

    continue-or-new-game

    Before starting an online battle, the progress of this level must be empty. Otherwise the battlefields of two online players will be different. If that happens, you need to restart the game without the modification, enter this level again but select “新游戏”, the right button, to reset the progress. It means “New Game”.

Configurations

Copy online_config.ini to the game root folder. You can set the server’s IP address and port number in it.

[Network]
ServerIP=127.0.0.1
Port=10000

Documents

The code comment style follows the Doxygen specification.

docs/Key Data and Functions.md describes key data and functions obtained by reverse engineering.

Class Diagram

classDiagram namespace state { class Role { <<enumeration>> Plante Zombie } class Config { vector~int~ zombies vector~int~ plants string server_ip int port } class State } State --> Role State --> Config State --> TcpSocket namespace network { class IpAddr { <<interface>> Version() int } class Ipv4Addr class Ipv6Addr class Socket { SetAddr(IpAddr) Bind() Close() } class TcpSocket { <<>> Connect(IpAddr) Send(data) size Recv(buffer) size } class Listener { Bind(IpAddr) Listen() Accept() TcpSocket Close() } class Packet { Recv(TcpSocket)$ Packet Send(TcpSocket) Write(data) size Read() data } } IpAddr <|.. Ipv4Addr IpAddr <|.. Ipv6Addr Socket --> IpAddr Socket <|-- TcpSocket Listener --> TcpSocket Packet ..> TcpSocket class Mod { <<interface>> Enable() Disable() } class ModLoader { Add(Mod) Load() } ModLoader o-- Mod class RemoveDefaultPlants Mod <|.. RemoveDefaultPlants class SetSunAmount Mod <|.. SetSunAmount class Hook { <<interface>> #From() address #To() address #JumpRet() optional~address~ } Mod <|-- Hook class BeforeLoadLevel Hook <|.. BeforeLoadLevel BeforeLoadLevel ..> CreateZombie BeforeLoadLevel ..> CreatePlant BeforeLoadLevel ..> LevelEnd BeforeLoadLevel ..> Listener BeforeLoadLevel ..> State class AfterLoadLevel Hook <|.. AfterLoadLevel AfterLoadLevel ..> RemoveDefaultPlants AfterLoadLevel ..> InitSlots class InitSlots Hook <|.. InitSlots InitSlots ..> State class LevelEnd Hook <|.. LevelEnd LevelEnd ..> State LevelEnd ..> Packet class CreateZombie Hook <|.. CreateZombie CreateZombie ..> State CreateZombie ..> Packet class CreatePlant Hook <|.. CreatePlant CreatePlant ..> State CreatePlant ..> Packet class Startup { Run() Stop() } Startup --> ModLoader Startup --> State

Issues & Bugs

  • The game sometimes crashes when creating zombies.
  • If the progress of I, Zombie Endless level is not empty, two players will have different battlefields.
  • In order to simplify the code, the running menu and automatic pause are disabled.

License

Distributed under the MIT License. See LICENSE for more information.

评论

暂无评论