DevD4v3/Capture-The-Flag
GitHub: DevD4v3/Capture-The-Flag
一款基于 .NET/C# 和 SampSharp 框架为 open.mp 打造的 GTA San Andreas 夺旗竞技游戏模式,支持 Docker 部署与多数据库后端。
Stars: 31 | Forks: 2
🎮 夺取旗帜 (Capture The Flag)
一款专为 open.mp 打造的快节奏 C# 游戏模式 —— 包含两支队伍、两面旗帜,以及纯粹的竞技混沌。
**Capture The Flag** 是一款适用于 [open.mp](https://github.com/openmultiplayer)(Open Multiplayer,GTA San Andreas 的一款多人模组)的游戏模式,使用 [SampSharp](https://github.com/ikkentim/SampSharp) 框架创建。
地图上有 2 面旗帜,每支队伍各有一面。玩家需要夺取敌方的旗帜并将其带回自己的基地。
## 目录
- [玩法](#gameplay)
- [截图](#screenshots)
- [使用的技术](#technologies-used)
- [编程语言](#programming-languages)
- [软件](#softwares)
- [框架和库](#frameworks-and-libraries)
- [测试](#testing)
- [软件工程](#software-engineering)
- [编程范式](#programming-paradigms)
- [软件模式](#software-patterns)
- [设计原则](#design-principles)
- [游玩要求](#requirements-to-play)
- [不使用 Docker 部署](#deployment-without-docker)
- [使用 Docker 部署](#deployment-with-docker)
- [凭据](#credentials)
- [如何成为管理员?](#how-to-become-an-admin)
- [支持的 RDBMS](#supported-rdbms)
- [SQLite](#sqlite)
- [MariaDB](#mariadb)
- [架构概述](#architectural-overview)
- [鸣谢](#credits)
- [地图作者](#mappers)
- [贡献](#contribution)
- [许可证](#license)
## 玩法
Beta 队与 Alpha 队进行对抗。目标是夺取敌方队伍的旗帜,并将其带回己方旗帜的出生点。
要得分,己方旗帜必须在基地中,因此队伍必须同时进行进攻和防守。团队协作和战术配合对于获胜至关重要。
比赛持续 15 分钟。时间结束时,夺取次数最多的队伍获胜。
如果两支队伍的夺取次数相同,则比赛以平局结束。
注意!敌人可以在雷达上看到携旗者。
在此视频中,您可以观看玩法演示:https://youtu.be/rsWCZaT4aBE
您还可以查看完整的播放列表:https://www.youtube.com/playlist?list=PLBM-9TMXSAJjsWn4zmg1ua7eof9Aj83fS
### 游戏规则
#### 游戏目标
- 夺取敌方队伍的旗帜并将其带回你的基地以完成一次得分。
- 当一支队伍达到特定的夺取次数时,比赛不会结束。
- 只有当计时器归零时,比赛才会结束。
#### 旗帜规则
**夺取敌方旗帜**
- 玩家可以通过在敌方基地拾取旗帜 pickup 来夺取敌方旗帜,该 pickup 在地图上以方形图标标记。
- 一名玩家一次只能携带一面旗帜。
**得分(完成一次夺取)**
- 要完成一次得分,必须满足以下所有条件:
- 玩家正携带敌方旗帜
- 玩家到达己方基地或得分区域
- 玩家所在队伍的旗帜位于其基地位置
- 如果己方旗帜已被盗或掉落在地图上的某处,则无法得分。
**携旗者死亡**
- 如果玩家在携带敌方旗帜时死亡:
- 旗帜将掉落在玩家当前所在位置的地面
- 该玩家不再处于携旗状态
**携旗者断开连接**
- 如果玩家在携带敌方旗帜时断开连接:
- 旗帜将掉落在玩家最后已知位置的地面
- 该玩家将被移出比赛
**携旗者无操作(暂停)**
- 如果携旗者保持暂停或不活动状态达 30 秒:
- 敌方旗帜将自动返回其基地
- 该玩家不再处于携旗状态
**旗帜自动返回**
- 如果旗帜一直掉落在地图上且未被收回:
- 它将在 120 秒后自动返回其基地
#### 死亡与重生
- 当玩家死亡时:
- 玩家将在其队伍基地重生
- 系统会为玩家随机选择一个出生位置(出生位置不是固定的)
- 不应用额外的重生保护
- 如果他们此前携带着旗帜,则适用旗帜掉落规则
#### 比赛结束条件
- 只有当计时器归零时,比赛才会结束。
- 夺取次数最多的队伍获胜。
- 如果两支队伍的夺取次数相同:
- 比赛以平局结束
- 没有突然死亡法
#### 回合过渡规则
- 每 15 分钟,当前地图结束并加载新地图。
- 在地图轮换期间:
- 所有已连接的玩家被冻结
- 玩家被切换至旁观者模式
- 在新回合开始前,会显示 10 秒的“加载地图”倒计时。
- 队伍将根据玩家在上一回合的表现进行重新平衡:
- 根据玩家的得分将其重新分配至各队伍
- 团队平衡由系统自动计算
- 玩家不会被发送至职业选择界面:
- 重生是自动的
- 出生点和队伍分配由系统决定
## 截图
sa-mp-000

sa-mp-001

sa-mp-002

sa-mp-003

sa-mp-004

## 使用的技术
### 编程语言
- [C Sharp](https://github.com/dotnet/csharplang)
- [Pawn](https://github.com/compuphase/pawn)
### 软件
- [.NET CLI](https://learn.microsoft.com/en-us/dotnet/core/tools)
- [Open Multiplayer](https://github.com/openmultiplayer)
- [CompileApp-FS](https://github.com/DevD4v3/CompileApp-FS)
- [Visual Studio 2022](https://visualstudio.microsoft.com)
- [vscode](https://github.com/microsoft/vscode)
- [MariaDB](https://github.com/mariadb)
- [SQLite](https://www.sqlite.org)
- [DB Browser for SQLite](https://sqlitebrowser.org)
- [HeidiSQL](https://github.com/HeidiSQL)
- [GitHub Actions](https://github.com/actions)
- [Git](https://github.com/git/git)
- [draw.io](https://app.diagrams.net)
- [Docker](https://github.com/docker)
- [Portainer](https://github.com/portainer/portainer)
### 框架和库
- [.NET SDK 10.0](https://github.com/dotnet/runtime)
- [SampSharp](https://github.com/ikkentim/SampSharp)
- [SampSharp.OpenMp.Streamer](https://github.com/OpenSamp/SampSharp.OpenMp.Streamer)
- [omp-streamer-component](https://github.com/OpenSamp/omp-streamer-component)
- [SmartFormat](https://github.com/axuno/SmartFormat)
- [MySqlConnector](https://github.com/mysql-net/MySqlConnector)
- [Microsoft.Data.Sqlite](https://www.nuget.org/packages/Microsoft.Data.SQLite)
- [Microsoft.Extensions.DependencyInjection](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection)
- [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder)
- [Microsoft.Extensions.Configuration.EnvironmentVariables](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.EnvironmentVariables)
- [BCrypt.Net-Next](https://github.com/BcryptNet/bcrypt.net)
- [DotEnv.Core](https://github.com/DevD4v3/dotenv.core)
- [YeSql.Net](https://github.com/ose-net/yesql.net)
- [seztion-parser](https://github.com/DevD4v3/seztion-parser)
- [Serilog.Sinks.Console](https://github.com/serilog/serilog-sinks-console)
- [Serilog.Sinks.File](https://github.com/serilog/serilog-sinks-file)
- [Serilog.Extensions.Logging](https://github.com/serilog/serilog-extensions-logging)
### 测试
- [NUnit](https://github.com/nunit/nunit)
- [Fluent Assertions](https://github.com/fluentassertions/fluentassertions)
## 软件工程
本项目应用了以下概念:
### 编程范式
- [面向对象编程 (OOP)](https://en.wikipedia.org/wiki/Object-oriented_programming)
- [结构化编程](https://en.wikipedia.org/wiki/Structured_programming)
### 软件模式
- [六边形架构](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software))
- [实体-组件-系统 (ECS)](https://en.wikipedia.org/wiki/Entity_component_system)
- [基于接口的编程](https://en.wikipedia.org/wiki/Interface-based_programming)
- [依赖注入](https://en.wikipedia.org/wiki/Dependency_injection)
- [仓储模式 (Repository Pattern)](https://deviq.com/design-patterns/repository-pattern)
- [操作结果模式](https://medium.com/@wgyxxbf/result-pattern-a01729f42f8c)
### 设计原则
- [关注点分离](https://en.wikipedia.org/wiki/Separation_of_concerns)
- [开闭原则](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)
- [依赖倒置原则](https://deviq.com/principles/dependency-inversion-principle)
- [显式依赖](https://deviq.com/principles/explicit-dependencies-principle)
## 游玩要求
- 您的本地计算机上必须安装 **DirectX 9**。
- 您必须在本地计算机上下载 [Grand Theft Auto: San Andreas](https://mega.nz/file/mIlnjKQK#ZuqNUB3xqB6_pul917dmwUQaohGuYVcN7YwbXHqn-v4)。
- 您必须下载 [open.mp launcher](https://github.com/openmultiplayer/launcher/releases/latest) 才能连接到服务器。
## 不使用 Docker 部署
- 您必须下载 [Visual C++ Redistributable x86](https://www.microsoft.com/en-us/download/details.aspx?id=48145) 才能加载诸如 SampSharp 和 Streamer 之类的插件。
- 您需要下载包含运行游戏模式所需文件的 [ctf-win.zip](https://github.com/DevD4v3/Capture-The-Flag/releases/latest) 压缩包。
- 下载完成后,根据您的需要修改 `.env` 文件。
- 运行 `omp-server.exe`。
## 使用 Docker 部署
- 克隆代码仓库:
```
git clone https://github.com/DevD4v3/Capture-The-Flag.git
```
- 切换目录:
```
cd Capture-The-Flag
```
- 将 `.env.example` 的内容复制到 `.env`:
```
cp .env.example .env
```
- 构建镜像并启动服务:
```
docker compose up --build -d
```
- 检查服务器日志,查看一切是否正常运行:
```
docker compose exec -it app cat log.txt
```
- 在您的 [omp-launcher](https://github.com/openmultiplayer/launcher/releases/latest) 中添加服务器 IP:
```
localhost:7777
```
## 凭据
下表显示了从游戏模式进行身份验证的默认凭据。
| 玩家名称 | 密码 |
|-------------------------|-----------------------------|
| Admin_Player | 123456 |
| Moderator_Player | 123456 |
| VIP_Player | 123456 |
| Basic_Player | 123456 |
请注意,这些凭据仅在您的数据库提供程序为**内存 (in-memory)** 模式时可用。在您的 .env 文件中,必须按如下方式进行设置。
```
DatabaseProvider=InMemory
```
## 如何成为管理员?
您必须在 `.env` 文件中添加您的名称和密钥:
```
ServerOwner__Name=MrDave # Your nickname in the game
ServerOwner__SecretKey=1234._%==?! # Specify the secret key to give me admin.
```
您必须指定您的密钥,在游戏中执行“**/givemeadmin**”命令时将会用到它。
## 支持的 RDBMS
### SQLite
- 从[此处](https://www.sqlite.org/download.html)下载 sqlite3 CLI(选择名为 **sqlite-tools-win-x86** 的文件)。
- 在根目录下创建一个名为 `.env` 的文件:
```
copy .env.example .env
```
- 您必须在 .env 文件中指定数据库提供程序的名称:
```
DatabaseProvider=SQLite
```
- 您必须指定数据库文件的位置:
```
SQLite__DataSource=C:\Users\mrdave\OneDrive\Desktop\gamemode.db
```
- 最后,您必须导入数据库:
```
sqlite3 gamemode.db < ./scripts/sqlite/gamemode.sql
```
查看[脚本](https://github.com/DevD4v3/Capture-The-Flag/tree/dev/scripts)以获取更多信息。
### MariaDB
- 安装 [MariaDb Server](https://mariadb.org/download) 并设置您的用户名和密码。
- 在根目录下创建一个名为 `.env` 的文件:
```
copy .env.example .env
```
- 您必须在 .env 文件中指定数据库提供程序的名称:
```
DatabaseProvider=MariaDB
```
- 您必须在 .env 文件中指定连接字符串:
```
MariaDB__Server=localhost
MariaDB__Port=3306
MariaDB__Database=gamemode
MariaDB__UserName=root
MariaDB__Password=123456789
```
- 最后,您必须导入数据库:
```
mariadb -uroot -p123456789 gamemode < ./scripts/mariadb/gamemode.sql
```
查看[脚本](https://github.com/DevD4v3/Capture-The-Flag/tree/dev/scripts)以获取更多信息。
## 架构概述
显示图表

### 主要组件
- **Application Core。** 包含名为“Capture The Flag”的游戏的所有逻辑,包括定义游戏玩法的规则和流程。
- **Persistence layer。** 包含所有数据访问逻辑。此层的目的是防止数据访问逻辑泄露至 application core 中。
- **Host Application。** 包含运行游戏模式所需的一切。它代表应用程序的入口点。
此层还执行其他任务,例如:
- 从 `.env` 文件加载应用程序设置。
- 选择数据库提供程序。
- 将服务注册到 DI Container。
- 将系统添加到服务中。
- 启用所需的 ECS 系统功能。
## 鸣谢
- [DevD4v3](https://github.com/DevD4v3/Capture-The-Flag) 创建了“Capture The Flag”游戏模式。
- [Parca_35](https://www.youtube.com/channel/UCQUOz-GEp0jMtmGzUEQWElQ) 帮助测试了游戏模式。
- [ikkentim](https://github.com/ikkentim/SampSharp) 创建了 SampSharp 框架。
- [Nickk888SAMP](https://github.com/Nickk888SAMP/TextDraw-Editor) 创建了 NTD(TextDraw Editor)。
- [samp-incognito](https://github.com/samp-incognito/samp-streamer-plugin) 创建了 streamer 插件。
- [Open Multiplayer](https://github.com/openmultiplayer) 创建了完全向后兼容 San Andreas Multiplayer (SA-MP) 的 Grand Theft Auto: San Andreas 多人模组。
### 地图作者
- Area66,作者 DragonZafiro。
- d_dust5、SA_Hill、de_aztec 和 de_dust2_small,作者 Elorreli。
- Compound 和 cs_rockwar,作者 Amirab。
- DesertGlory、fy_iceworld2 和 de_dust2x3,作者 TheYoungCapone。
- EntryMap 和 TheConstruction,作者 B4MB1[MC]。
- fy_snow,作者 UnuAlex。
- fy_snow2,作者 mihaibr。
- de_dust2,作者 JamesT85。
- Aim_Headshot,作者 haubitze。
- Aim_Headshot2,作者 Niktia_Ruchkov。
- de_dust2x1,作者 SpikY_。
- de_dust2x2,作者 Amads。
- de_dust2x4 贴图制作,作者 excamunicado。
- WarZone,作者 Samarchai。
- WarZone2,作者 iMaster。
- cs_assault,作者 Ghost-X。
- GateToHell 和 TheWild,作者 Zniper。
- TheBunker,作者 Dr.Pawno。
- cs_deagle5,作者 SENiOR。
- mp_jetdoor,作者 saawan。
- Simpson,作者 Risq。
- ZM_Italy - 未知。
- zone_paintball,作者 Famous。
- mp_island,作者 Leo。
- Baron's Playground (RC Battlefield V2),作者 Pyraeus。
- cs_train、cs_opposition、fy_iceworld 和 de_dust2x5,作者 denis_32。
## 贡献
欢迎任何形式的贡献!请记住,您不仅可以在代码方面做出贡献,还可以在文档方面做出贡献,甚至可以改进测试。
请按照以下步骤操作:
- Fork 本仓库
- 创建您的自定义分支 (git checkout -b my-new-change)
- 提交您的更改 (git commit -am 'Add some change')
- 推送至该分支
- 创建新的 Pull Request
## 许可证
本项目基于 [GNU Affero General Public License v3.0](https://github.com/DevD4v3/Capture-The-Flag/blob/dev/LICENSE) 获得许可。
标签:Open.MP, SA-MP, SampSharp, 夺旗模式, 游戏模组, 请求拦截