fuzziqersoftware/newserv
GitHub: fuzziqersoftware/newserv
一个支持全版本 Phantasy Star Online 的私有服务器、代理和逆向工程工具集。
Stars: 236 | Forks: 59
# newserv
newserv 是一个针对 Phantasy Star Online (PSO) 的游戏服务器、代理和逆向工程工具。**要快速上手使用 newserv,只需阅读[服务器设置](#server-setup)和[如何连接](#how-to-connect)部分。**
本项目包含了很久以前社区逆向工程的代码,此后已被包含在许多项目中。它还包含来自 Phantasy Star Online 本身的一些游戏数据,这些数据最初是由 Sega 创建的。
如果您发现错误或有功能请求,请随时提交 GitHub issues。我想让服务器尽可能稳定和完整,但我不能保证我会及时回复问题,因为这是一个主要是为了逆向工程的乐趣而进行的个人项目。如果您想自己为 newserv 做贡献,也欢迎提交 pull requests。
请参阅 TODO.md 以获取我整理的已知问题和未来工作列表,或访问 GitHub issue tracker 查看社区提交的问题和请求。
**目录**
* 背景
* [历史](#history)
* [其他服务器项目](#other-server-projects)
* [在其他项目中使用 newserv](#using-newserv-in-other-projects)
* [为 newserv 做贡献](#contributing-to-newserv)
* [兼容性](#compatibility)
* 设置
* [服务器设置](#server-setup)
* [PC 和 BB 的客户端补丁目录](#client-patch-directories)
* [如何连接](#how-to-connect)
* 功能与配置
* [用户账户](#user-accounts)
* [安装任务](#installing-quests)
* [物品表和掉落模式](#item-tables-and-drop-modes)
* [跨版本游戏](#cross-version-play)
* [服务器端存档](#server-side-saves)
* [Episode 3 功能](#episode-3-features)
* [内存补丁、客户端函数和 DOL 文件](#memory-patches-and-client-functions)
* [将 newserv 用作代理](#using-newserv-as-a-proxy)
* [聊天命令](#chat-commands)
* [REST API](#rest-api)
* [非服务器功能](#non-server-features)
# 历史
这个项目的历史本质上反映了从我刚开始这个爱好直到现在我作为一名软件工程师的发展历程。如果你不关心这个故事,请跳到下面的“兼容性”或“设置”部分。
我最初购买 PSO GC 是因为我听说了 PSUL,并想在 GameCube 上运行自制软件。这条路径最终导致了 [GCARS-CS](https://github.com/fuzziqersoftware/gcars-cs),但那是另一个故事了。
在玩了一段时间 PSO(包括离线和在线)后,我在 2003 年的某个时候写了一个名为 Khyps 的代理。那是回到官方 Sega 服务器的时代,漏洞没有被及时解决或根本没有解决。使用自己的代理或 Action Replay 代码(这是一个以后再讲的故事)的恶意玩家发送服务器会盲目转发的无效命令,并导致接收客户端崩溃,这种情况很常见。这些崩溃不仅仅是带来不便;它们还可能损坏你的存档数据,摧毁你可能投入在寻找物品和升级角色上的数小时工作。
有一段时间,使用代理上网基本上是必须的,这样代理才能阻止这些无效命令。Khyps 的设计主要考虑了这一功能,尽管它也实现了一些方便的作弊功能,比如给自己或其他玩家无限 HP 的能力,以及允许你在不使用游戏内传送装置的情况下传送到不同的地方。
在 Khyps 之后,我接受了编写服务器的更大挑战,这导致了 2005 年某个时候 Khyller 的诞生。这是我编写的第一个任何类型的服务器。这个项目最终演变成一个支持我有权访问的游戏的所有版本的全功能环境——当时是 PC、GC 和 BB。(然而,通过阅读古老的源文件,我怀疑 Khyller 的 BB 支持非常漏洞百出。)随着 Khyller 的发展,代码变得越来越笨重,充斥着我从未清理过的调试垃圾和我多年来习得的奇怪编码模式。我对 C++ 语言的理解也是可悲的不完整(与现在相反,现在它仍然不完整,但不是可悲的不完整),这导致 Khyller 本质上是一个包含几个类的 C 项目。
在 2006 年或 2007 年的某个时候,我放弃了 Khyller 并从头开始重建了整个项目,结果就是 Aeon。Aeon 的代码比 Khyller 干净得多,但仍然相当难以处理,而且它缺少我最初编写的一些更深奥的功能(例如,将任何任务转换为下载任务的能力)。此外,代码仍然有一些稳定性问题……事实证明 Aeon 的并发原语根本就是不正确的。我在上任何真正的计算机工程课之前自己推导了互斥锁的概念,但实现不正确。我使竞争窗口尽可能小,但 Aeon 在看似正常运行几天后仍会随机崩溃。
在 Aeon 出现之初,它也被称为 newserv,你可能会在网上找到一些文件名像 `newserv-b3.zip` 这样的测试版。我发布了测试版 1、2 和 3,然后发布了测试版 5 的全部源代码,并在上大学时停止了该项目的工作。这大概是我从主要在 Windows 上编写软件转向主要在 macOS 和 Linux 上编写软件的时候,所以 Aeon beta 5 是我编写的最后一个专门针对 Windows 的服务器。(你现在看到的 newserv 很难在 Windows 上编译,但确实可以工作。)
在 long 时间没有接触 PSO 以及在技术能力上有了很多专业和个人发展之后,2018 年 10 月的某个时候,我在阅读我的旧代码档案时回忆起了往事。当我遇到 Aeon 时,不知何故受到了启发,我花了一个周末和几个晚上的时间再次重写了整个项目,清理了我十一年前使用的古老模式,用简单的 STL 容器替换了整个模块,并取消了更多的支持文件,转而使用配置自动检测。代码现在已经足够现代和稳定,我不再为它的存在感到尴尬,就像我对 Aeon beta 5 的源代码和我的 Khyller 档案(幸好没有其他人见过)感到尴尬一样。
## 其他服务器项目
独立于本项目,还有许多其他的 PSO 服务器。我所知道的(或曾经)公开的服务器按大致的时间顺序列在这里:
* (2000 年代早期) **[Schtserv](https://schtserv.com/)**:第一个公共访问的 PSO 服务器,由 Schthack 用 Delphi 编写。Schtserv 是唯一另一个支持 Episode 3 的非官方服务器,其实现基于 newserv(而 newserv 又基于 Sega 的)。
* (2005) **Khyller**:我早期尝试支持 PSO PC、GC 和 BB 的产物。详见上文。
* (2006) **Aeon**:我的第二次尝试。比 Khyller 好,但仍然不可靠。
* (2008) **Tethealla**:一个相当广泛的 PSOBB 实现,由 Sodaboy 用 C 语言编写。Tethealla 的公开版本已被[正式弃用](https://www.pioneer2.net/community/threads/tethealla-server-forums-removal.26365/),因为它现在已有 15 年以上的历史,但闭源开发仍在继续。[Ephinea](https://ephinea.pioneer2.net/) 是该项目的延续。其他几个现代 PSOBB 服务器也是 Tethealla 最初公开版本的分支。
* (2008) **[Sylverant](https://sylverant.net/)** [(源码)](https://sourceforge.net/projects/sylverant/):第二个公共访问的 PSO 服务器,由 BlueCrab 用 C 语言编写。
* (2015) **[Archon](https://github.com/dcrodman/archon)**:一个由 Drew Rodman 用 Go 语言编写的 PSOBB 服务器。
* (2015) **[Idola](https://github.com/HybridEidolon/idolapsoserv)**:一个由 HybridEidolon 用 Rust 语言编写的 PSOBB 服务器。功能状态未知;该项目已存档。
* (2017) **[Aselia](https://github.com/Solybum/Aselia)**:一个由 Soly 用 C# 编写的 PSOBB 服务器。看起来这个项目曾计划在某个时候开源,但这(尚)未发生。
* (2018) **newserv**:就是本项目。
* (2019) **[Mechonis](https://gitlab.com/sora3087/mechonis)**:一个由 TrueVision 用 TypeScript 编写的具有微服务架构的 PSOBB 服务器。
* (2020) **[Booma.Server](https://github.com/HelloKitty/Booma.Server)**:一个由 Glader 在 Soly 的帮助下用 C# 编写的 PSOBB 服务器。
* (2021) **[Phantasmal World](https://github.com/DaanVandenBosch/phantasmal-world)**:一套 PSO 工具,包括基于 Web 的模型查看器和任务构建器,以及一个 PSO 服务器,由 Daan Vanden Bosch 编写。
* (2021) **[Elseware](http://git.sharnoth.com/jake/elseware)**:一个由 Jake 用 Rust 语言编写的 PSOBB 服务器。
## 在其他项目中使用 newserv
您可以在您自己的开源项目中自由使用 newserv 的代码;唯一的条件是,如果您使用 newserv 的代码,您的项目中必须包含 LICENSE 文件的内容。您的项目不必也使用 MIT 许可证;您可以使用您想要的任何许可证。
如果您想在您的项目中使用 newserv 的部分内容,有两种简单的方法可以做到这一点并遵守许可规定:
* 如果您使用 newserv 的大量代码,您可以将 newserv 的 LICENSE 文件的副本放在您的存储库中,与您自己的许可证文件并列,或者将 newserv 许可证的内容包含在您自己的许可证文件中。
* 如果您只使用 newserv 的几个文件,您可以将 LICENSE 文件的内容复制并粘贴到每个复制文件开头的注释中。
一些更有可能有用的文件是:
* **src/CommandFormats.hh**: 所有已知版本的游戏中使用的所有网络命令及其格式的完整列表
* **src/CommonItemSet.hh/cc**: ItemPT 文件、商店定义文件和 tekker 调整表的格式
* **src/DCSerialNumbers.hh/cc**: PSO DC 序列号验证算法和序列号生成器
* **src/ItemData.hh**: 物品格式参考
* **src/ItemCreator.hh/cc**: 来自 Episodes 1&2 的逆向工程物品生成器(用于所有版本)
* **src/ItemParameterTable.hh**: ItemPMT.prs 中许多结构的格式
* **src/Map.hh/cc**: 地图文件(.dat/.evt)结构、对象/敌人类型和参数列表,以及逆向工程的挑战模式随机敌人生成算法
* **src/QuestScript.cc**: 所有版本上所有任务操作码的完整列表,以及它们的参数和行为
* **src/RareItemSet.hh/cc**: ItemRT 文件(稀有物品掉落表)的格式
* **src/SaveFileFormats.hh**: 所有版本的存档文件结构定义
* **src/Episode3/DataIndexes.hh**: Episode 3 文件结构,包括卡片定义格式和地图/任务格式
* **system/item-tables/names-v4.json**: 所有物品的名称,按 data1 的前 3 个字节索引
## 为 newserv 做贡献
本项目的目标是:
* 构建稳定、可扩展的 PSO 服务器软件,包括所有原版功能以及可选的现代便利设施、功能和作弊。
* 记录 PSO 网络协议、文件格式和游戏机制的内部细节。这主要通过代码中的注释来完成。
这是一个个人项目;没有官方开发团队、官方网站或官方 newserv 实例。欢迎提交 issues 和 pull requests,但请仅添加您创建的、已经公开的或您有权公开发布的内容(例如任务或补丁)。
# 兼容性
newserv 支持所有已知的 PSO 版本,包括各种开发原型。此表列出了 newserv 支持的所有版本。(NTE 代表网络试玩版;GameCube 测试版被称为试玩版,但为了一致性,我们仍然使用 NTE 缩写。)
| 版本 | 大厅 | 游戏 | 代理 |
|-----------------|----------|----------|----------|
| DC NTE | 是 | 是 | 是 |
| DC 11/2000 | 是 | 是 | 是 |
| DC 12/2000 | 是 | 是 | 是 |
| DC 01/2001 | 是 | 是 | 是 |
| DC V1 | 是 | 是 | 是 |
| DC 08/2001 | 是 | 是 | 是 |
| DC V2 | 是 | 是 | 是 |
| PC NTE | 是 (1) | 是 | 是 |
| PC | 是 | 是 | 是 |
| GC Ep1&2 NTE | 是 | 是 | 是 |
| GC Ep1&2 | 是 | 是 | 是 |
| GC Ep1&2 Plus | 是 | 是 | 是 |
| GC Ep3 NTE | 是 | 是 (2) | 是 |
| GC Ep3 | 是 | 是 | 是 |
| Xbox Ep1&2 Beta | 是 (3) | 是 (3) | 是 (3) |
| Xbox Ep1&2 | 是 (3) | 是 (3) | 是 (3) |
| BB (vanilla) | 是 | 是 | 是 |
| BB (Tethealla) | 是 | | 是 |
*注意:*
1. *这是唯一一个没有任何方法识别玩家账户的 PSO 版本——没有序列号或用户名。因此,必须在 config.json 中启用 AllowUnregisteredUsers 以支持 PC NTE,并且 PC NTE 玩家每次连接时都会收到一个随机的公会卡号。为防止滥用,可以在 config.json 中禁用 PC NTE 支持。*
2. *Episode 3 NTE 战斗未经充分测试;某些功能可能无法工作。有关 NTE 和最终版本之间已知差异的列表,请参阅 notes/ep3-nte-differences.txt。NTE 和非 NTE 玩家不能互相战斗。*
3. *PSO Xbox 通过 Xbox Live 连接,因此您无法轻松为此版本的游戏托管私人服务器。请参阅[如何连接](#pso-xbox)部分。*
# 设置
## 服务器设置
目前 newserv 可在 macOS、Windows 和 Ubuntu Linux 上运行。它很可能也能在其他 Linux 发行版上运行。
### Windows/macOS
1. 从[发布页面](https://github.com/fuzziqersoftware/newserv/releases)下载最新的 release.zip 文件。
2. 将压缩包的内容解压到您计算机上的某个位置。
3. 进入 system/ 文件夹,在文本编辑器中打开 config.json,并根据您的喜好进行编辑。文件中有注释描述了所有选项的作用。如果您想要默认行为,大多数选项可以保留不变,但在 Windows 上,您必须更改 LocalAddress 和 ExternalAddress。
4. (可选)如果您计划在 newserv 上玩 Blue Burst,请设置补丁目录。有关详细信息,请参阅[客户端补丁目录](#client-patch-directories)。
5. 运行 newserv 可执行文件。
### Linux
目前没有 Linux 的预编译版本。要在 Linux 上运行 newserv,您必须从源代码构建它——请参阅下面的部分。
### 从源代码构建
要在 macOS 或 Linux 上构建:
1. 安装您的平台所需的依赖项:
* macOS: `brew install cmake asio libiconv`
* Linux: `sudo apt-get install cmake libasio-dev`(或使用您的 Linux 发行版的包管理器)
2. 构建并安装 [phosg](https://github.com/fuzziqersoftware/phosg) 和 [resource_dasm](https://github.com/fuzziqersoftware/resource_dasm)。
3. 在 newserv 目录中运行 `cmake . && make`。
构建 newserv 后,根据需要编辑 system/config.example.json **并将其重命名为 system/config.json**(请注意,预编译版本不需要此步骤),如果您计划玩 Blue Burst,请设置[客户端补丁目录](#client-patch-directories),然后在 newserv 的目录中运行 `./newserv`。
服务器有一个交互式 shell,可用于进行更改,例如管理用户账户、更新服务器配置、管理 Episode 3 比赛等。输入 `help` 并按 Enter 查看所有命令。
在 Linux 和 macOS 上,服务器也响应 SIGUSR1 和 SIGUSR2。SIGUSR1 执行相当于 shell 的 `reload config` 命令,该命令重新加载 config.json 但不重新加载任何依赖文件(因此任务、Episode 3 地图等将不会被重新加载)。SIGUSR2 执行相当于 shell 的 `reload all` 命令,该命令重新加载所有内容。
要以其他方式使用 newserv(例如用于转换数据),请参阅本文档的末尾。
### 从源代码构建
当前版本的 newserv 是在 macOS 构建机器上使用 mingw-w64 交叉编译的,并手动安装了必要的库。设置这样的构建环境很繁琐,不推荐;建议直接使用发布版本。
以下是 Windows 构建过程的粗略大纲。只有在您熟悉设置构建环境并且能够处理沿途可能遇到的问题时,才应自行尝试此操作。
1. 安装最新版本的 MinGW 和 CMake。
2. 将 zlib、libiconv、asio、phosg 和 resource_dasm 构建并安装到您的 MinGW 环境中。
3. 启用符号链接克隆 newserv 存储库:`git clone -c core.symlinks=true https://github.com/fuzziqersoftware/newserv.git`
4. 通过 CMake 构建 newserv。
## 客户端补丁目录
newserv 为 PSO PC 和 PSO BB 游戏数据实现了补丁服务器。您放在 system/patch-bb 或 system/patch-pc 目录中的任何文件或目录在连接到补丁服务器时都会同步到客户端。
对于 Blue Burst 设置,以下内容对于流畅的体验是强制性的:
1. 浏览到您选择的客户端的数据目录。
2. 复制所有 `map_*.dat` 文件、`map_*.evt`、`unitxt_*` 文件以及 `data.gsl` 文件,并将它们放在 `system/patch-bb/data` 中。
3. 如果您使用的是 Tethealla 客户端的游戏文件,请在 system/patch-bb/data 中制作 `unitxt_j.prs` 的副本并将其命名为 `unitxt_e.prs`。(如果 `unitxt_e.prs` 已经存在,请用复制的文件替换它。)
如果您没有 BB 客户端,或者您使用的是来自其他来源的 Tethealla 客户端,可以在这里找到与 newserv 兼容的 Tethealla 客户端:[英文](https://web.archive.org/web/20240402011115/https://ragol.org/files/bb/TethVer12513_English.zip)/[日文](https://web.archive.org/web/20240402013127/https://ragol.org/files/bb/TethVer12513_Japanese.zip)。这些客户端会自动连接到 127.0.0.1 (localhost)。
对于 BB 客户端,newserv 从补丁数据中读取一些文件以实现游戏逻辑,因此某些游戏文件在服务器和客户端之间同步非常重要。newserv 在 system/maps/bb-v4 目录中包含这些文件的默认值,但如果这些文件与客户端的文件副本不匹配,游戏中将会发生奇怪的行为。
为了使服务器启动更快,newserv 会缓存补丁目录中文件的修改时间、大小和校验和。如果补丁服务器似乎出现异常行为,请尝试删除相关补丁目录中的 .metadata-cache.json 文件,以强制 newserv 重新计算所有校验和。此外,在校验和被缓存的情况下,newserv 可能实际上不会加载补丁文件的数据,直到客户端需要它为止。因此,在 newserv 运行时修改补丁树的任何部分都可能导致客户端看到它的不一致视图。
补丁目录内容缓存在内存中。如果您更改了这些文件,可以在交互式 shell 中运行 `reload patch-indexes` 以使更改生效,而无需重启服务器。
## 如何连接
### PSO DC
根据您拥有的 PSO DC 版本,连接到 newserv 实例的说明会有所不同。
如果您拥有 NTE、USv1、EUv1 或 EUv2 以及宽带适配器,请在运行 newserv 的 DNS 服务器的情况下,将宽带 DNS 地址编辑为 newserv 的 IP 地址。否则,必须修补光盘或使用 codebreaker 代码来移除 Hunter License 服务器检查和/或将 PSO 重定向到 newserv 实例。修补光盘或创建 codebreaker 代码超出了本文档的范围。
### Flycast 上的 PSO DC
如果您正在模拟 PSO DC,通过在 Flycast 的 `emu.cfg` 文件中的 `[network]` 下设置以下选项,NTE、USv1、EUv1 和 EUv2 版本将连接到 newserv:
- DNS = 您的 newserv 的服务器地址(newserv 的 DNS 服务器必须在 53 端口运行)
- EmulateBBA = yes
- Enable = yes
还需要将任何 DNS 信息保存到 Dreamcast 的闪存中才能使用 BBA——最简单的方法是在 USv2 中使用网站选项,然后选择保存到闪存选项。
如果服务器运行在与 Flycast 相同的机器上,这可能不起作用,即使您将 Flycast 的 DNS 查询指向您的本地 IP 地址(而不是 127.0.0.1)。在这种情况下,您可以修改内存中加载的可执行文件,使其连接到您想要的任何地方。newserv 附带了一个脚本,可以在 macOS 上执行此操作;类似的技巧可以在 Linux 上使用 scanmem 或在 Windows 上使用 Cheat Engine 手动完成。要使用该脚本,请执行以下操作:
1. 构建并安装 [memwatch](https://github.com/fuzziqersoftware/memwatch)。
2. 启动 Flycast 并运行 PSO。(您必须在运行脚本之前启动 PSO;如果在加载游戏之前运行脚本,它将无法工作。)
3. 运行 `sudo patch_flycast_memory.py `。将 `` 替换为 PSO 想要连接的主机名(您可以通过使用 Wireshark 并查找 DNS 查询来找到这一点)。脚本可能需要一分钟;您可以在它运行时继续使用 Flycast,但在脚本完成之前不要开始在线游戏。
4. 运行 newserv 并在 PSO 中开始在线游戏。
如果您使用这种方法,每次在 Flycast 中启动 PSO 时都必须运行脚本,但如果您在不重启模拟的情况下开始另一个在线游戏,则不必再次运行它。
如果使用 JPv1、JPv2 或 USv2,还需要移除 Hunter Licence 服务器检查,可以使用光盘补丁或 codebreaker 代码。修补光盘或创建 codebreaker 代码超出了本文档的范围。
### PSO PC
PSO PC 在 `pso.exe` 中有其连接地址。使用您想要连接的连接地址对可执行文件进行十六进制编辑。要搜索和替换的常见服务器地址是:
- pso20.sonic.isao.net
- sg207634.sonicteam.com
- pso-mp01.sonic.isao.net
- gsproduc.ath.cx
- sylverant.net
我的 PSO PC 版本的服务器地址从 pso.exe 中的偏移量 0x29CB34 开始。如果您只是想连接到本地运行的 newserv 实例,请将这些地址更改为 "localhost"(不带引号)。或者,您可以在 Windows hosts 文件(C:\Windows\System32\drivers\etc\hosts)中添加一个条目,以将连接重定向到 127.0.0.1 (localhost) 或任何其他 IP 地址。
### 实机 GameCube 上的 PSO GC
您可以通过在游戏的网络设置中将默认网关和 DNS 服务器地址设置为 newserv 的地址,使 PSO 连接到 newserv。newserv 的 DNS 服务器必须在 53 端口运行,并且必须对 GameCube 可访问。如果您玩的不是 PSO Plus 或 Episode III,假设您已经在 config.json 中将 LocalAddress 设置为您的 PC 的私有 IP 地址,这应该是您需要做的所有事情。
如果您拥有 PSO Plus 或 Episode III,它将不想连接到与 GameCube 本身位于同一局域网内的服务器,这是由 GameCube 的 IP 地址和子网掩码确定的。有几种方法可以解决这个问题。
Sodaboy 描述了一种相当简单的方法,即在路由器配置中将 PSO 和 DNS 端口转发到您的 PC 的私有 IP 地址(PSO 端口在 config.json 中,并且都是 TCP;DNS 端口是 53 并且是 UDP)。然后,在 config.json 中将 LocalAddress 和 ExternalAddress 设置为您的外部 IP 地址(来自例如 whatismyip.com)。大多数路由器将允许您甚至从局域网内连接到您的公共 IP 地址,但 GameCube 会认为它正在连接到不同的网络,因此它不会拒绝连接。如果您关心安全性并且不希望您的服务器公开访问,您可以使用 Windows 防火墙或 Linux 上的 UFW 阻止您打开的端口上的传入连接,来自您指定的 IP 地址的连接除外。
另一种方法是在同一台 PC 上使用两个网络接口,并告诉 GameCube 连接到似乎位于不同网络上的那个接口。例如,如果您的 GameCube 位于 10.0.0.x 子网,您的 PC 地址是 10.0.0.5,您可以在您的 PC 上创建一个假网络适配器(或使用现有的真实适配器),其 IP 地址位于与 GameCube 不同的子网,例如 192.168.0.8。然后,在 PSO 的网络配置中,将默认网关和 DNS 服务器地址设置为 192.168.0.8,并在 config.json 中将 LocalAddress 设置为 192.168.0.8,PSO 应该会连接。这是我早年在 Windows 上主要开发软件时所做的,但我已经很多年没试过了。
### Wii 或 Wii U 上的 PSO GC
使用 Wii 或 Wii U 连接到 newserv 需要 Wii 或 vWii 进行软改。如何做到这一点超出了本文档的范围。
Nintendont 包含 BBA 模拟,并且兼容所有 PSO GameCube 版本,Episodes I&II Trial Edition 除外。要使用 Nintendont,请在 Nintendont 的设置中启用 BBA 模拟,并按照上一节(PSO GC on a real GameCube)中的说明进行操作。
Devolution 包含调制解调器模拟,并且兼容所有 PSO GameCube 版本,包括 Episodes I&II Trial Edition。newserv 可以充当 PPP 服务器,Devolution 可以直接连接到该服务器。为此:
1. 根据 config.json 中的注释启用 PPPRawListen 选项。
2. 启动 newserv。
3. 在游戏的网络设置中,将用户名和密码设置为任意内容(不能为空),并将电话号码设置为 newserv 在启动期间输出到控制台的号码。(它将在所有启动日志消息的末尾。)如果您的 Wii 与 newserv 位于同一网络,请使用本地号码;否则,请使用外部号码。
### Dolphin 上的 PSO GC
如果您使用的是 HLE BBA 类型,请将 BBA 的 DNS 服务器地址设置为erv 的 IP 地址,它应该可以工作。(如果 newserv 与 Dolphin 位于同一台机器上,您将需要使用指向 127.0.0.1 的 Action Replay 代码进行连接,因为 PSO 拒绝来自相同 IP 地址的 DNS 查询。)设置 PSO 的网络设置与下面列出的相同。
如果您使用的是 TAP(非 tapserver)BBA 类型,您必须为您的 tap 接口适当设置 PSO 的网络设置。在 PSO 的网络设置中将 DNS 服务器地址设置为 newserv 的 IP 地址。
如果您使用的是 tapserver BBA 或调制解调器类型,您可以使其通过 tapserver 接口连接到在同一台机器上运行的 newserv 实例。为此:
1. 在配置窗口的 GameCube 窗格中,将 SP1 设备设置为 Broadband Adapter (tapserver) 或 Modem Adapter (tapserver)。
2. 点击 SP1 菜单旁边的 "..." 按钮。如果您使用的是 tapserver BBA,请在框中输入 `127.0.0.1:5059`。如果您使用的是 tapserver 调制解调器,请在框中输入 `127.0.0.1:5058`。(如果 newserv 与 Dolphin 不在同一台机器上运行,请将 127.0.0.1 替换为 newserv 的 IP 地址。)
3. 在 PSO 的网络设置中,启用 DHCP("Automatically obtain an IP address"),将 DNS 服务器地址设置为 "Automatic",并将 DHCP Hostname 保留为 "Not set"。将代理服务器设置留空。
4. 开始在线游戏。
### PSO Xbox
不幸的是,您无法轻松为 PSO Xbox 托管私人服务器,因为游戏的 Xbox 版本通过 Xbox Live 隧道传输其连接。有一个名为 [Insignia](https://insignia.live/) 的 Xbox Live 现代替代品,它支持三个主要的 PSO Xbox 服务器,但目前不支持其他私人 PSO 服务器。
### PSO BB
PSO BB 客户端已被修改并以多种不同的形式分发。newserv 支持大多数(但不是所有)常见的发行版。与其他版本不同,各种 BB 客户端通常有不同的地图文件。客户端和服务器拥有相同的地图文件很重要,因此请务必根据您将在 newserv 上使用的客户端设置补丁目录。(有关设置说明,请参阅[客户端补丁目录](#client-patch-directories)部分。)
原始的日文和美版 PSO BB 可与 newserv 一起使用(最后的日文版本可以在[这里](https://archive.org/details/psobb_jp_setup_12511_20240109/)找到)。要让它们连接到您的服务器,请执行以下操作之一:
* 使用像 [AzureFlare](https://github.com/Repflez/AzureFlare) 这样的直接补丁程序。
* 编辑您的 hosts 文件,将客户端的目标地址重定向到 localhost 或您的服务器地址。
* 编辑 psobb.exe 以指向您的 newserv 实例。原始客户端使用各种版本的 ASProtect 打包,因此这比简单地在十六进制编辑器中打开可执行文件并查找/替换一些字符串更复杂。
或者,您可以使用 Tethealla 客户端([英文](https://web.archive.org/web/20240402011115/https://ragol.org/files/bb/TethVer12513_English.zip)或[日文](https://web.archive.org/web/20240402013127/https://ragol.org/files/bb/TethVer12513_Japanese.zip))。如果服务器与客户端位于同一台 PC 上,并且您不打算让任何外部玩家玩,这些 Tethealla 客户端将自动连接到服务器,无需任何修改。此版本的客户端未打包,您可以在 psobb.exe 的偏移量 0x56D724 处找到连接地址。用您的服务器的主机名或 IP 地址覆盖这些地址,您应该能够连接。
### 允许外部玩家连接
如果您想接受来自本地网络之外的连接,您需要在配置文件中将 ExternalAddress 设置为您的公共 IP 地址,并且您可能需要在路由器的 NAT 配置中打开一些端口——具体来说,是 config.json 中 PortConfiguration 中列出的所有 TCP 端口。
对于 GC 客户端,您必须使用 newserv 的内置 DNS 服务器或设置您自己的 DNS 服务器。如果您希望外部客户端能够使用您的 DNS 服务器,您必须将 UDP 端口 53 转发到您的 newserv 实例。然后,远程玩家可以通过在其客户端的网络配置中输入您的 DNS 服务器的 IP 地址来连接到您的服务器。
# 服务器功能配置
## 用户账户
默认情况下,newserv 不要求用户在游戏前预先注册;相反,服务器将在每个玩家首次连接时自动创建一个账户。这些账户没有特殊权限。您可以在服务器的 shell 中查看、创建、编辑和删除用户账户(在 shell 中运行 `help` 以查看如何执行此操作)。
许可证是玩家可以用来登录的一组凭据。有六种类型的许可证:
* *DC NTE 许可证*由一个 16 个字符的序列号和 16 个字符的访问密钥组成。
* *DC 许可证*由一个 8 个字符的十六进制序列号和一个 8 个字符的访问密钥组成。
* *PC 许可证*与 DC 许可证格式相同,但用于 PC v2。
* *GC 许可证*由一个 10 位十进制序列号、一个 12 个字符的访问密钥和一个最多 8 个字符的密码组成。
* *XB 许可证*由一个最多 16 个字符的玩家标签、一个 16 个字符的十六进制用户 ID 和一个 16 个字符的十六进制账户 ID 组成。
* *BB 许可证*由一个最多 16 个字符的用户名和一个最多 16 个字符的密码组成。
每个账户可以有多个许可证。要向现有账户添加许可证,请在 shell 中使用 `add-license`。
在 BB 上,角色数据的作用域是许可证,但系统和公会卡数据的作用域是账户。也就是说,一个拥有多个 BB 许可证的账户可以有超过 4 个角色(每个许可证最多 4 个),但他们都将共享相同的队伍成员资格和公会卡列表。
您可能希望授予您的账户提升的权限。为此,请运行 `update-account ACCOUNT-ID flags=root`(将 ACCOUNT-ID 替换为您实际的 account-id)。您也可以使用 update-account 编辑账户的其他部分;有关更多信息,请参阅帮助文本。
## 安装任务
newserv 自动在 system/quests/ 目录的子目录中查找任务。要安装您自己的任务,或使用您使用代理的 Save Files 选项保存的任务,只需将它们放在那里的子目录之一中并适当命名。子目录及其行为(例如,它们应该出现在哪些游戏模式中以及针对哪些 PSO 版本)在 config.json 的 QuestCategories 字段中定义。
在类别目录中,任务文件应命名为 `q###-VERSION-LANGUAGE.EXT`(尽管 `q` 被忽略,可以是任何字母)。每个文件名中的字段是:
- `###`:任务编号(这并不重要;它应该在 PSO 版本中唯一)
- `VERSION`:dn = Dreamcast NTE,dp = Dreamcast 11/2000 原型,d1 = Dreamcast v1,dc = Dreamcast v2,pcn = PC NTE,pc = PC,gcn = GameCube NTE,gc = GameCube Episodes 1 & 2,gc3 = Episode 3(见下文),xb = Xbox,bb = Blue Burst
- `LANGUAGE`:j = Japanese,e = English,g = German,f = French,s = Spanish
- `EXT`:文件扩展名(见下表)
对于 .dat 文件,`LANGUAGE` 标记可以省略。如果存在,则该 .dat 文件将仅用于该语言的任务;如果省略,则该 .dat 文件将用于该任务的所有语言。
例如,GameCube 版本的 Lost HEAT SWORD 位于名为 `q058-gc-e.bin` 和 `q058-gc.dat` 的两个文件中。newserv 知道这些文件是任务,因为它们位于 system/quests/ 目录中,它知道它们用于 PSO GC,因为文件名包含 `-gc`,它知道这是任务的英文版本,因为 .bin 文件名以 `-e` 结尾(即使 .dat 文件名没有),并且它将它们放在 Retrieval 类别中,因为文件位于 system/quests/ 内的 retrieval/ 目录中。
有些任务具有描述服务器应如何处理它们的额外 JSON 元数据文件。这些元数据文件的命名通常类似于其 .bin 和 .dat 对应文件,但如果元数据适用于所有 PSO 版本的所有语言的任务,则也可以省略 `VERSION` 标记。有关所有可用选项以及如何使用它们,请参阅 system/quests/retrieval/q058.json 中的注释。其中一些选项是:
- 如果某些前置任务未清除或其他条件未满足,则禁用或隐藏任务
- 启用任务以便在任务进行中时加入
- 覆盖普通和/或稀有物品表并设置允许的掉落模式
有些任务可能还包括一个 .pvr 文件,其中包含任务中使用的图像。这些文件的命名类似于其 .bin 和 .dat 对应文件。
GameCube 和 Xbox 任务格式非常相似,但 newserv 对它们的处理方式不同。如果您想为 GameCube 和 Xbox 客户端使用相同的任务文件,可以将其中一个制作成指向另一个的符号链接。
存在多种 PSO 任务格式;newserv 支持所有这些格式。它还可以将任何已知格式解码为标准 .bin/.dat 格式。具体来说:
| 格式 | 扩展名 | 支持 | 解码操作 |
|------------------|-----------------------|------------|------------------|
| Compressed | .bin and .dat | 是 | None (1) |
| Compressed Ep3 | .bin or .mnm | 是 (4) | None (1) |
| Uncompressed | .bind and .datd | 是 | compress-prs (2) |
| Uncompressed Ep3 | .bind or .mnmd | 是 (4) | compress-prs (2) |
| Source | .bin.txt and .dat | 是 | None (5) |
| VMS (DCv1) | .bin.vms and .dat.vms | 是 | decode-vms |
| VMS (DCv2) | .bin.vms and .dat.vms | Decode (3) | decode-vms (3) |
| GCI (decrypted) | .bin.gci and .dat.gci | 是 | decode-gci |
| GCI (with key) | .bin.gci and .dat.gci | 是 | decode-gci |
| GCI (no key) | .bin.gci and .dat.gci | Decode (3) | decode-gci (3) |
| GCI (Ep3 NTE) | .bin.gci or .mnm.gci | Decode (3) | decode-gci (3) |
| GCI (Ep3) | .bin.gci or .mnm.gci | 是 | decode-gci |
| DLQ | .bin.dlq and .dat.dlq | 是 | decode-dlq |
| DLQ (Ep3) | .bin.dlq or .mnm.dlq | 是 | decode-dlq |
| QST (online) | .qst | 是 | decode-qst |
| QST (download) | .qst | 是 | decode-qst |
*注意:*
1. *这是默认格式。您可以通过运行 `newserv decompress-prs FILENAME.bin FILENAME.bind`(以及类似地对于 .dat -> .datd)将这些转换为未压缩格式*
2. *与 (1) 类似,要压缩未压缩的任务文件:`newserv compress-prs FILENAME.bind FILENAME.bin`(以及类似地对于 .datd -> .dat)*
3. *在将任务放入服务器的任务目录之前,使用解码操作将这些任务转换为 .bin/.dat 格式。如果您知道加密种子(序列号),请使用 `--seed=` 选项将其作为十六进制字符串传递。如果您不知道加密种子,newserv 会为您找到它,这可能会花费很长时间。*
4. *Episode 3 任务不放在 system/quests 目录中。请参阅下面的 [Episode 3 section](#episode-3-features) 部分。*
5. *任务源可以使用 `newserv assemble-quest-script FILENAME.txt` 汇编成 .bin 或 .bind 文件。请参阅 system/quests/retrieval/q058-gc-e.bin.txt 以获取带注释的示例;这是 Lost HEAT SWORD 的 GameCube 英文版。*
Episode 3 下载任务仅包含 .bin 文件——没有相应的 .dat 文件。Episode 3 下载任务文件可以使用 .mnm 扩展名而不是 .bin 命名,因为该格式与标准地图文件(在 system/ep3/maps/ 中)相同。这些文件可以以上述任何格式编码,除了 .qst。
当 newserv 在启动期间索引任务时,如果有任何任务损坏或格式无法识别,它会发出警告(但不会失败)。
任务内容缓存在内存中,但如果您更改了任务目录的内容,可以通过在交互式 shell 中运行 `reload quest-index` 来重新索引任务,而无需重启服务器。新任务将立即可用,但任何已经在进行任务的游戏将继续使用旧版本的任务,直到这些任务结束。
## 物品表和掉落模式
newserv 在所有游戏上支持服务器端物品生成,最早的 DC 原型(NTE 和 11/2000)除外。默认情况下,游戏的行为与原始服务器上的行为相同——在除 BB 之外的所有版本中,物品掉落由每个游戏中的领队客户端控制,而在 BB 上,物品掉落由服务器控制。
物品掉落有五种不同的可用行为:
* `disabled`(或 `none`):箱子或敌人不会掉落任何物品。
* `client`:游戏领队生成物品,所有物品对所有玩家可见,任何玩家都可以捡起任何物品。这是所有游戏版本的默认模式,但如果游戏领队在 BB 上,则不能使用此模式。
* `shared`:服务器生成物品,所有物品对所有玩家可见,任何玩家都可以捡起任何物品。如果游戏领队在 BB 上,这是默认模式。
* `private`:服务器生成物品,但每个玩家可能会从任何箱子或敌人那里获得不同的物品。如果玩家在敌人被击败时不与敌人在同一区域,他们将不会从中获得任何物品。玩家掉落的物品对所有人可见。
* `duplicate`:服务器生成物品,每个玩家将从任何箱子或敌人那里获得相同的物品,但每个玩家都有每个物品的一个副本(并且每个玩家只能看到自己的物品副本)。如果玩家在敌人被击败时不与敌人在同一区域,他们将不会从中获得任何物品。玩家掉落的物品不会重复,并且对所有人可见。
在 `private` 和 `duplicate` 模式下,没有抢在另一个玩家之前捡起物品的动机,因为其他玩家不能捡起你看到从箱子和敌人掉落的物品。但是,如果你捡起一个物品然后把它扔掉,它就可以被任何玩家看到并捡起。
可以在游戏过程中随时使用 `$dropmode` 聊天命令更改掉落模式。如果在某些物品已经掉落后更改模式,现有物品将保留其可见性(也就是说,在 private 模式下掉落的物品仍然不能被其他玩家捡起,因为它们是在模式更改之前掉落的)。您可以在 config.json 中配置默认使用哪些掉落模式以及允许玩家选择哪些模式。请参阅 AllowedDropModes 和 DefaultDropMode 键上方的注释。
在服务器掉落模式中,用于生成普通物品的物品表位于 `system/item-tables/ItemPT-*` 文件中。(V1 也使用 V2 文件。)稀有物品表位于 `rare-table-*.json` 文件中。与原始格式不同,可以让每个敌人以不同的比率掉落多个不同的稀有物品,尽管默认表从不这样做。
## 跨版本游戏
所有版本的 PSO 都可以在大厅中看到彼此并与之互动。默认情况下,newserv 允许 V1 和 V2 玩家一起玩游戏,并允许 GC 和 Xbox 玩家一起玩游戏。您可以使用 config.json 中的 CompatibilityGroups 设置更改这些规则,以允许所有版本一起玩游戏,或阻止版本之间一起玩游戏。
无论兼容性组设置如何,都有几个始终适用的跨版本限制:
* 如果游戏创建者未选择允许 DC V1 玩家,则 DC V1 玩家无法加入 DC V2 游戏。
* 如果难度级别设置为 Ultimate 或游戏模式为 Battle 或 Challenge,则 DC V1 玩家无法加入游戏。
* 只有 GC、Xbox 和 BB 玩家可以加入 Episode 2 的游戏。
* 只有 BB 玩家可以加入 Episode 4 的游戏。
* Episode 3 玩家不能加入非 Episode 3 游戏,反之亦然。
V1/V2 兼容性和 GC/Xbox 兼容性已经过充分测试,但其他情况则没有。对于如何跨主要版本处理物品还没有给予太多关注;例如,如果您启用 V2/GC 兼容性,可能会存在错误。请将此类错误作为 GitHub issues 报告。
在跨版本游戏中,当使用任何服务器掉落模式时,服务器使用对应于领队版本和 section ID 的掉落表。(例如,如果 DC V1 玩家是游戏领队,则将使用 rare-table-v1.json,即使在 V2 玩家加入之后。)如果 BB 玩家是领队并使用 `client` 掉落模式,则服务器生成物品,就像处于 `shared` 模式一样。
## 服务器端存档
newserv 能够在服务器端保存角色数据。对于 PSO BB,这当然是必需的,但此功能也可以用于其他 PSO 版本。
每个账户有 4 个 BB 角色槽和 16 个非 BB 角色文件槽。非 BB 槽独立于 BB 槽,可以使用 `$savechar ` 和 `$loadchar ` 命令访问(槽编号为 1 到 16)。`$savechar` 复制您当前扮演的角色并将数据保存在服务器上,而 `$loadchar` 执行相反的操作,用服务器上保存的数据覆盖您当前的角色。请注意,您可以加载从不同版本的 PSO 保存的角色,这允许您在游戏之间轻松转移角色。在 v1 和 v2 上,如果加入游戏,`$loadchar` 所做的更改将被撤消;要永久保存您的更改,请在使用命令后断开与大厅的连接。
您可以使用 `$checkchar ` 查看有关服务器上保存的角色基本信息(不影响您当前的角色)。您可以使用 `$deletechar ` 删除以前保存的角色。
还有命令 `$bbchar `,其行为类似于 `$savechar`,但将角色数据写入不同账户中的 BB 角色槽(槽编号为 1 到 4)。这可用于将角色从早期版本“升级”到 BB。
具体保存和加载哪些数据取决于游戏版本:
| 游戏 | 物品栏 | 角色 | 选项/聊天 | 任务标志 | 银行 | 战斗/挑战 |
|----------------------|-----------|-----------|---------------|-------------|------|------------------|
| PSO DC v1 原型 | 是 | 是 | 无 | 无 | 无 | 不适用 |
| PSO DC v1 | 是 | 是 | 无 | 无 | 无 | 不适用 |
| PSO DC v2 | 是 | 是 | 是 | 是 | 是 | 是 |
| PSO PC (v2) | 是 | 是 | 无 | 无 | 无 | 仅保存 |
| PSO GC NTE | 是 | 是 | 是 | 是 | 是 | 是 |
| PSO GC (非 Plus) | 是 | 是 | 是 | 是 | 是 | 是 |
| PSO GC Plus (1) | 仅保存 | 仅保存 | 无 | 无 | 无 | 仅保存 |
| PSO GC Ep3 (1) | 无 | 仅保存 | 无 | 无 | 无 | 仅保存 |
| PSO Xbox | 是 | 是 | 是 | 是 | 是 | 是 |
| PSO BB | 是 | 是 | 是 | 是 | 是 | 是 |
*注意*:
1. *如果在 config.json 中启用 EnableSendFunctionCallQuestNumber,则 $savechar 和 $loadchar 可以在这些版本上保存和恢复所有角色数据,就像在 GC non-Plus 上一样。Episode 3 角色存在于单独的命名空间中;也就是说,您不能使用 $savechar 和 $loadchar 将 Ep3 角色转换为非 Ep3,反之亦然。*
## Episode 3 功能
newserv 支持许多 Episode 3 独有的功能:
* CARD 战斗。并非所有能力组合都经过测试,因此如果您发现功能或卡片能力没有按预期工作,请提出 GitHub issue 并描述情况(攻击卡、防御卡以及未工作的能力或条件)。
* 观战队伍。
* 比赛。(但它们的工作方式与 Sega 的比赛不同——见下文)
* 下载任务。
* 交易卡片。
* 参与卡片拍卖。(拍卖内容必须在 config.json 中配置。)
* 大厅中的装饰。目前仅支持图像;游戏还支持在大厅中加载自定义 3D 模型,但 newserv(尚)未实现此功能。
### 战斗记录
进行战斗后,您可以使用 `$saverec` 命令保存战斗记录。然后,您可以通过在大厅中使用 `$playrec` 命令稍后重播战斗——这将创建一个观战队伍并像实时发生一样播放战斗记录。请注意,旧版本的 Dolphin 似乎在播放战斗记录时经常触发一个错误,该错误导致模拟器崩溃并显示消息 `QObject::~QObject: Timers cannot be stopped from another thread`。为避免这种情况,请使用最新版本的 Dolphin。
### 比赛
比赛的工作方式与 Sega 服务器上的不同。可以使用 `create-tournament` shell 命令创建比赛,该命令使玩家能够注册。(使用 `help` 查看所有参数——有很多!)`start-tournament` shell 命令开始比赛(并阻止进一步注册),但这不会安排任何比赛。相反,准备好进行下一场比赛的玩家都可以站在同一个 CARD 大厅中大厅传送点附近的 4 人战斗桌旁,比赛将自动开始。
这些比赛语义意味着同一比赛中可以同时进行多场比赛,并且在下一轮开始之前不必完成一轮中的所有比赛——只有每场单独比赛之前的比赛必须完成,该比赛才能进行。
可以在 config.json 中配置赢得比赛比赛的 Meseta 奖励。
### Episode 3 文件
Episode 3 状态和游戏数据存储在 system/ep3 目录中。其中的文件有:
* card-definitions.mnr: 压缩的卡片定义列表,在连接时发送给 Episode 3 客户端。可以通过编辑此文件来更改卡片属性和能力。
* card-definitions.mnrd: 上述文件的解压版本。如果存在,newserv 将使用它而不是压缩版本,因为它更容易编辑。
* card-text.mnr: 压缩的卡片文本存档。通常仅用于调试。
* card-text.mnrd: 解压的卡片文本存档;格式与 TextCardE.bin 相同。通常仅用于调试。
* com-decks.json: 比赛中使用的 COM 牌组。此文件中的默认牌组来自 Sega 服务器的日志,因此该文件不包含 Sega 制作的所有 COM 牌组——其余的可能已经失传。
* maps/: 在线自由战斗和任务地图(.mnm/.bin/.mnmd/.bind 文件)。newserv 附带默认的在线地图,以及一些粉丝制作的变体和任务,以帮助新玩家入门。在 maps/ 目录中,每个子目录被视为一个单独的类别,并且可以是可选的可下载或在战斗设置柜台可用。每个子目录中的 category.json 文件指定类别的行为;有关记录的示例,请参阅 system/ep3/maps/online/category.json。
* tournament-state.json: 所有活跃比赛的状态。每当任何比赛因任何原因更改状态时(例如,创建/启动/删除比赛或解决一场比赛),都会自动写入此文件。
没有用于 Episode 3 地图和任务的公共编辑器,但该格式在 src/Episode3/DataIndexes.hh 中进行了相当彻底的描述(请参阅 MapDefinition 结构)。您需要使用 `newserv decompress-prs ...` 在编辑之前解压 .bin 或 .mnm 文件,但您不需要再次压缩它即可使用它——只需将 .bind 或 .mnmd 文件放在 maps 目录中,newserv 就会使其可用。
与任务一样,Episode 3 卡片定义、地图和任务缓存在内存中。如果您更改了这些文件,可以在交互式 shell 中运行 `reload ep3-cards` 或 `reload ep3-maps` 以使更改生效,而无需重启服务器。
## 内存补丁和客户端函数
您可以将汇编文件放在 system/client-functions 目录中,文件名类似于 PatchName.VERS.patch.s,它们将出现在支持客户端函数的客户端的 Patches 菜单中。客户端函数是用 SH-4、PowerPC 或 x86 汇编编写的,并在 newserv 启动时编译。汇编系统的功能记录在 system/client-functions/System/WriteMemoryGC.ppc.s 的注释中。
客户端函数文件名中的 VERS 标记指的是客户端函数适用的游戏的特定版本。某些版本根本不支持接收客户端函数。*注意:newserv 使用较短的 GameCube 版本约定,其中标记为 DOL-XXXX-0-0Y 的光盘是版本 1.Y。PSO 社区似乎在某些地方使用约定 1.0Y 代替,但这些是相同的版本。例如,newserv 称为 v1.4 的版本与 v1.04 相同,并在光盘背面标记为 DOL-GPOJ-0-04。*
特定版本是:
| 游戏 | VERS | CPU 架构 |
|------------------------------|------|--------------------------------|
| PSO DC Network Trial Edition | 1OJ1 | 不支持客户端函数 |
| PSO DC 11/2000 原型 | 1OJ2 | 不支持客户端函数 |
| PSO DC 12/2000 原型 | 1OJ3 | 不支持客户端函数 |
| PSO DC 01/2001 原型 | 1OJ4 | 不支持客户端函数 |
| PSO DC v1 JP | 1OJF | 不支持客户端函数 |
| PSO DC v1 US | 1OEF | 不支持客户端函数 |
| PSO DC v1 EU | 1OPF | 不支持客户端函数 |
| PSO DC 08/06/2001 原型 | 2OJ4 | SH-4 |
| PSO DC 08/22/2001 原型 | 2OJ5 | SH-4 |
| PSO DC v2 JP | 2OJF | SH-4 |
| PSO DC v2 US | 2OEF | SH-4 |
| PSO DC v2 EU | 2OPF | SH-4 |
| PSO PC (v2) Trial Edition | 2OJT | 不支持客户端函数 |
| PSO PC (v2) 04/2002 | 2OJW | 不支持客户端函数 |
| PSO PC (v2) 02/2003 | 2OJZ | 不支持客户端函数 |
| PSO GC Trial Edition | 3OJT | PowerPC |
| PSO GC v1.2 JP | 3OJ2 | PowerPC |
| PSO GC v1.3 JP | 3OJ3 | PowerPC |
| PSO GC v1.4 (Plus) JP | 3OJ4 | PowerPC |
| PSO GC v1.5 (Plus) JP | 3OJ5 | PowerPC (1) |
| PSO GC v1.0 US | 3OE0 | PowerPC |
| PSO GC v1.1 US | 3OE1 | PowerPC |
| PSO GC v1.2 (Plus) US | 3OE2 | PowerPC (1) |
| PSO GC v1.0 EU | 3OP0 | PowerPC |
| PSO GC Ep3 Trial Edition | 3SJT | PowerPC |
| PSO GC Ep3 JP | 3SJ0 | PowerPC |
| PSO GC Ep3 US | 3SE0 | PowerPC (1) |
| PSO GC Ep3 EU | 3SP0 | PowerPC (1) |
| PSO Xbox Beta | 4OJB | x86 |
| PSO Xbox JP Disc | 4OJD | x86 |
| PSO Xbox JP TU | 4OJU | x86 |
| PSO Xbox US Disc | 4OED | x86 |
| PSO Xbox US TU | 4OEU | x86 |
| PSO Xbox EU Disc | 4OPD | x86 |
| PSO Xbox EU TU | 4OPU | x86 |
| PSO BB JP 1.25.11 | 59NJ | x86 |
| PSO BB JP 1.25.13 | 59NL | x86 |
| PSO BB Tethealla | 59NL | x86 |
*注意:*
1. *仅在 config.json 中设置 EnableSendFunctionCallQuestNumbers 时,这些版本才支持客户端函数。有关更多信息,请参阅那里的注释。*
newserv 附带上述许多版本的一组补丁。这些整理在 system/client-functions/ 内的子目录中。
### DOL 加载器
您可以将 DOL 文件放在 system/dol 目录中,它们将出现在 GC 客户端的 Programs 菜单中。在那里选择 DOL 文件会将文件加载到 GameCube 的内存中并运行它,就像旧的自制软件加载器(PSUL 和 PSOload)一样。为此,system/client-functions/System 目录中必须存在 ReadMemoryWordGC.ppc.s、WriteMemoryGC.ppc.s 和 RunDOL.ppc.s。这已在 Dolphin 上测试过,但未在真正的 GameCube 上测试过,因此结果可能会有所不同。
与其他类型的数据一样,函数和 DOL 文件缓存在内存中。如果您更改了这些文件,可以在交互式 shell 中运行 `reload functions` 或 `reload dol-files` 以使更改生效,而无需重启服务器。
我主要是为了文档目的而构建 DOL 加载功能。现在,在未修改的 GameCube 上加载自制代码有很多更好的方法,但据我所知,目前没有这种方法的另一个开源实现。
## 将 newserv 用作代理
如果您想在远程服务器上在线玩而不是运行自己的服务器,newserv 还包括一个 PSO 代理。目前这适用于 PSO GC,可能适用于 PC 和 DC;它也适用于特定情况下的某些 BB 客户端。
要将代理用于 PSO DC、PC 或 GC,请将条目添加到 config.json 中相应的 ProxyDestinations 字典中,然后运行 newserv 并照常连接到它(见下文)。您将在主菜单中看到一个 "Proxy server" 选项,您可以选择要连接的远程服务器。
要将代理用于 PSO BB,请在 config.json 中设置 ProxyDestination-BB 条目。如果设置了此选项,它基本上会禁用所有 BB 客户端的游戏服务器——所有 BB 客户端将被代理到指定的目的地。不幸的是,因为 PSO BB 为数据服务器阶段和角色选择使用一组不同的处理程序,所以在游戏中没有办法向玩家展示选项列表,就像在 PSO PC 和 PSO GC 上那样。
当您在 PSO DC、PC、GC 或 Xbox 上并通过 newserv 的代理连接到远程服务器时,从大厅柜台选择 Change Ship 或 Change Block 操作会将您送回 newserv 的主菜单,而不是远程服务器的飞船或区块选择菜单。您可以通过再次从代理服务器菜单中选择它来返回您刚才所在的服务器。
启动代理会话时有多种可用选项。除非另有说明,否则默认情况下所有选项都关闭。这些选项是:
* **Chat commands**: 在代理会话中启用聊天命令(默认开启)。
* **Chat filter**: 在聊天消息和信息板中启用转义序列(默认开启)。
* **Player notifications**: 当任何玩家加入或离开您所在的游戏或大厅时显示消息。
* **Block pings**: 阻止客户端发送的自动 ping,并自动响应来自服务器的 ping 命令。
* **Infinite HP**: 每当您受到攻击时自动治愈您。但是,一击杀死您的攻击仍然会杀死您。
* **Infinite TP**: 每当您使用任何技巧时自动恢复您的 TP。
* **Switch assist**: 在单人游戏中解锁需要两个或四个玩家的门,当您踩在其中一个开关上时。
* **Infinite Meseta**(仅限 Episode 3):给您 1,000,000 Meseta,无论远程服务器发送的值如何。
* **Block events**: 禁用远程服务器发送的节日事件。
* **Block patches**: 阻止任何 B2(补丁)命令到达客户端。
* **Save files**: 当远程服务器发送几种文件时保存它们的副本。文件被写入当前目录(通常是包含 system/ 目录的目录)。然后,只需将文件移动到 system/ 目录中的适当位置并适当重命名,保存的文件就可以与 newserv 一起使用。可以保存这些类型的文件:
* 在线任务和下载任务(保存为 .bin/.dat 文件)
* GBA 游戏(保存为 .gba 文件)
* 补丁(保存为 .bin 文件并反汇编为 .txt 文件)
* 来自 BB 会话的玩家、系统和公会卡数据(保存为 .psochar、.psosys、.psosysteam 和 .psocard 文件)
* 来自 BB 会话的流文件数据(保存为 ItemPMT、BattleParamEntry、ItemMagEdit 和 PlyLevelTbl 文件)
* Episode 3 在线任务和地图(保存为 .mnmd 文件)
* Episode 3 下载任务(保存为 .mnm 文件)
* Episode 3 卡片定义(保存为 .mnr 文件)
* Episode 3 媒体更新(保存为 .gvm、.bml 或 .bin 文件)
远程服务器可能会尝试为您分配一个与您在 newserv 上拥有的公会卡号不匹配的公会卡号。代理重写传输中的命令,使其看起来像远程服务器为您分配了与您在 newserv 上拥有的相同的公会卡号,但如果远程服务器有一些外部集成(例如论坛或 Discord 机器人),它们将使用远程服务器认为它已分配给您的公会卡号。当您首次连接到远程服务器时,远程服务器分配的号码会显示给您,您可以在大厅或游戏期间使用 `$li` 命令检索它。
某些聊天命令(见下文)在代理上具有相同的基本功能,但具有不同的效果或条件。此外,还有一些服务器 shell 命令会影响代理上的客户端(在 shell 中运行 `help` 以查看它们是什么)。如果只有一个代理会话打开,shell 的代理命令将影响该会话。否则,您必须使用 `on` 前缀指定要影响的会话——例如,要在 C-17 的会话中发送聊天消息,您需要运行 `on C-17 chat ...`。
## 聊天命令
newserv 支持玩家可以通过在游戏中聊天使用的各种命令。任何以 `$` 开头的聊天消息都被视为聊天命令。(如果您真的想发送以 `$` 开头的聊天消息,请输入 `$$`。)在 DC 11/2000 原型上,所有聊天命令使用 `@` 代替 `$`,因为 `$` 不会出现在英文虚拟键盘上。
某些命令仅适用于不在代理会话中的客户端。聊天命令是:
* Information commands
* `$li`: 显示您所在的大厅或游戏的基本信息。如果您在代理上,显示有关您的连接的信息(远程公会卡号、客户端 ID 等)。
* `$si`: 显示有关服务器的基本信息。
* `$ping`: 显示从服务器到您的往返 ping 时间。在代理上,显示从您到代理以及从代理到服务器的 ping 时间。
* `$matcount`(仅限非代理):显示您使用的每种材料类型的数量。
* `$killcount`(仅限非代理):显示您当前装备的武器的击杀计数。如果您在游戏中且不在 BB 上,则该值仅在物品进入游戏时是准确的。
* `$itemnotifs `: 启用物品掉落通知消息。如果游戏启用了私人掉落,您只会在掉落的物品对您可见时看到通知;您不会收到其他玩家掉落的通知。这些模式是:
* `off`: 不显示通知。
* `rare`: 当稀有物品掉落时您会收到通知。
* `on`: 当任何物品掉落时您会收到通知,Meseta 除外。
* `every`: 当任何物品掉落时您会收到通知,包括 Meseta。
* `$announcerares`: 启用或禁用您的稀有物品发现公告。这决定了您发现的稀有物品是否会向游戏和服务器宣布,而不是您是否看到其他人发现稀有物品的公告。
* `$what`(仅限非代理):显示地面上最近物品的类型、名称和属性。
* `$where`: 显示您当前的楼层数和坐标。主要用于调试。
* `$qfread `(仅限非代理):显示您玩家数据中的任务计数器的值。字段名称在 config.json 中定义。
* Basic debugging commands(不需要特殊权限)
* `$whatobj` and `$whatene`(仅限非代理):告诉您离您的位置最近的对象或敌人生成点是什么,以及它的坐标和对象或敌人 ID。完整的定义也会打印到服务器的日志中。
* `$qcheck `(仅限非代理):显示任务标志的值。如果您在游戏中,显示该游戏中标志的值;如果您在大厅中,显示该任务标志为您的角色保存的值(仅限 BB)。
* `$qgread `(仅限非代理):显示任务计数器("global flag")的值。
* `$sound `: 播放给定的声音(仅限 GC)。
* Restricted debugging commands(需要 `$debug` 权限)
* `$debug`: 启用调试模式。您需要用户账户中的 DEBUG 标志才能使用此命令。启用调试会做几件事:
* 您将能够使用本节中的其余命令。
* 当您执行某些操作时,您将看到来自服务器的游戏内消息,例如杀死敌人、打开箱子或拨动开关。
* 您将在加入游戏时看到稀有种子值和楼层变化。
* 您将被放置在大厅和游戏中最后可用的槽位,而不是第一个,除非您加入 BB 单人模式游戏。
* 您将能够加入任何 PSO 版本的游戏,而不仅仅是通常启用跨版本游戏的版本。有关详细信息,请参阅上面的“跨版本游戏”部分。
* `$readmem `: 从给定地址读取 4 个字节并向您显示值。
* `$writemem `: 将数据写入给定地址。数据不需要是任何特定大小。
* `$nativecall [arg1 ...]`(仅限 GC):在您的客户端上调用原生函数。仅支持在寄存器中传递的参数;不支持调用采用许多参数的函数。
* `$quest `(仅限非代理):通过任务编号加载任务。可用于在只有一个玩家在场的情况下加载战斗或挑战任务。如果指定任务的元数据文件中设置了 AllowStartFromChatCommand 字段,则此命令不需要 `$debug`。
* `$qcall `: 在您的客户端上调用任务函数。
* `$qset ` or `$qclear `: 为游戏中的所有人设置或清除任务标志。如果您在大厅中且在 BB 上,请设置或清除角色文件中任务标志的保存值。
* `$qgwriteflag-num> `(仅限非代理):为您自己设置任务计数器("global flag")的值。
* `$qsync `: 仅为您自己设置任务寄存器的值。`` 应该是 rXX(例如 r60)或 fXX(例如 f60);如果是后者,`` 被解析为浮点值而不是整数。
* `$qsyncall `: 为游戏中的所有人设置任务寄存器的值。`` 应该是 rXX(例如 r60)或 fXX(例如 f60);如果是后者,`` 被解析为浮点值而不是整数。
* `$swset [floor] ` and `$swclear [floor] `: 设置或清除开关标志。如果未给出楼层,则设置或清除当前楼层的标志。
* `$swsetall`: 设置当前楼层的所有开关标志。这将解锁所有门,禁用所有激光栅栏,触发所有光/毒开关等。
* `$gc`(仅限非代理):向您自己发送您自己的公会卡。
* `$sc `: 向您自己发送命令。
* `$ss `: 向远程服务器(如果在代理会话中)或游戏服务器发送命令。
* `$sb `: 向您自己以及远程服务器或游戏服务器发送命令。
* `$auction`(仅限 Episode 3):调出 CARD Auction 菜单,即使游戏中少于 4 名玩家或您没有 VIP 卡。
* `$makeobj [coords...] [angles...] [params...]`: 创建一个地图对象。这仅针对少数特定的客户端版本实现。类型是一个整数,例如 `273` 或 `0x0107`。坐标指定方式例如 `x:30 y:0 z:-25.5`;如果未指定坐标,对象将在玩家坐标处创建。角度指定方式例如 `r:0 p:0x1000 w:-0x400`(分别对应 roll、pitch 和 yaw)。参数指定方式例如 `1:2.0 2:0.0 5:0x4000`;任何未指定的参数都将设置为零。该对象仅为调用它的玩家创建,不会添加到服务器的地图状态中;如果该对象发送更新命令(例如 6x0B),可能会导致断开连接。
* 个人状态命令
* `$arrow `: 更改你的大厅箭头颜色。颜色可以通过数字(0-12)或名称指定(red, blue, green, yellow, purple, cyan, orange, pink, white, white2, white3, 或 black)。
* `$secid `: 设置你的覆盖 section ID。运行此命令后,你创建的任何游戏都将使用你的覆盖 section ID 来计算稀有掉落,而不是你的角色实际的 section ID。如果你在游戏中且是游戏的队长,这也会立即更改服务器创建物品时使用的物品表。要恢复到你的实际 section ID,请运行不带名称的 `$secid`。在代理上,如果远程服务器控制物品掉落,这将不起作用。如果服务器不允许在任何地方使用作弊模式(即 config.json 中的 "CheatModeBehavior" 为 "Off"),此命令无效。
* `$rand `: 设置你的覆盖随机种子(指定为 32 位十六进制值)。这将使你创建的任何游戏使用给定的种子来生成稀有敌人和物品掉落。在代理上,此命令可能导致与同一游戏中的其他玩家不同步,因为他们不会看到被覆盖的随机种子。要移除覆盖,请运行不带参数的 `$rand`。如果服务器不允许在任何地方使用作弊模式(即 config.json 中的 "CheatModeBehavior" 为 "Off"),此命令无效。
* `$ln [name-or-type]`: 设置大厅编号。仅对你可见。此命令的存在是因为某些非大厅地图可以加载为具有无效大厅编号的大厅。有关此处的可接受值,请参阅信息菜单中的 "GC lobby types" 和 "Ep3 lobby types" 条目。请注意,非大厅地图没有大厅计数器,因此如果不再次使用 `$ln` 或 `$exit`,则无法退出大厅。在游戏服务器上,`$ln` 会立即重新加载大厅;在代理上,直到你自己加载另一个大厅它才会生效(这意味着你可能必须使用 `$exit` 来退出)。运行不带参数的此命令可返回默认大厅。
* `$swa`: 启用或禁用开关辅助。启用后,当你踩下任何所需的开关时,服务器将在非任务游戏中解锁双人门和四人门。
* `$exit`: 如果你在大厅中,将你发送到主菜单(如果你在代理会话中,这将结束该会话)。如果你在游戏或观察者团队中,将你发送到大厅(但不会结束代理会话)。如果你在非 Episode 3 游戏中且没有进行中的任务,则不执行任何操作。
* `$patch `: 在你的客户端上运行补丁。`` 必须与服务器上的补丁名称完全匹配。
* 角色数据命令(仅限非代理)
* `$switchchar `(仅限 BB):无需登出即可切换到你帐户中的另一个角色。
* `$savechar `: 将你当前的角色数据保存在服务器的指定槽位中。有关更多详细信息,请参阅[服务器端存档部分](#server-side-saves)。
* `$loadchar `: 从服务器上的指定槽位加载角色数据,并用它替换你当前的角色。有关更多详细信息,请参阅[服务器端存档部分](#server-side-saves)。
* `$bbchar `: 将你当前的角色数据保存在服务器的另一个帐户的 BB 角色槽位中。有关更多详细信息,请参阅[服务器端存档部分](#server-side-saves)。
* `$checkchar [slot]`: 告知你有关先前使用 `$savechar` 保存的服务器端角色的基本信息。如果未给出 `slot`,则告知你哪些槽位已使用,哪些是空闲的。
* `$deletechar `: 删除先前使用 `$savechar` 保存的服务器端角色。
* `$edit `: 修改你的角色数据。有关详细信息,请参阅[使用 $edit](#using-edit) 部分。
* Blue Burst 玩家命令(仅限非代理)
* `$bank [number]`: 切换你当前的银行,以便你可以访问其他角色的银行(如果 `number` 为 1-4)或你的共享帐户银行(如果 `number` 为 0)。如果未给出 `number`,则切换回你当前角色的银行。
* `$save`: 立即保存你的角色、系统和 Guild Card 数据。(默认情况下,你的角色在线时每 60 秒保存一次,你的帐户和 Guild Card 数据在更改时保存。)
* 游戏状态命令(仅限非代理)
* `$maxlevel `: 设置玩家加入当前游戏的最大等级。(这仅在加入时适用;如果玩家加入后在游戏中升级超过此等级,他们不会被踢出,但如果离开则无法重新加入。)
* `$minlevel `: 设置玩家加入当前游戏的最小等级。
* `$password `: 设置游戏的加入密码。要解锁游戏,请运行后面没有任何内容的 `$password`。
* `$dropmode [mode]`: 更改当前游戏中物品掉落的行为方式。`mode` 可以是 `none`、`client`、`shared`、`private` 或 `duplicate`。如果未给出 `mode`,则告知你当前的掉落模式而不更改它。有关更多信息,请参阅[物品表和掉落模式部分](#item-tables-and-drop-modes)。
* `$persist`: 启用或禁用当前游戏的持久性。启用持久性后,当最后一名玩家离开时,游戏不会被删除。敌人、对象和开关的状态将被保存,留在地上的物品不会被删除。(但是,如果你处于私人或复制掉落模式,敌人掉落的物品会被删除 - 为了确保某个物品不会被删除,你可以将其捡起并再次丢弃。)如果游戏空闲时间过长(默认为 15 分钟),则会被删除。
* Episode 3 命令(仅限非代理)
* `$spec`: 切换 Episode 3 游戏的允许观众标志。如果在禁用此标志时有观众正在观看,他们将被送回大厅。
* `$inftime`: 切换无限时间模式。必须在开始战斗前使用。如果启用了无限时间模式,则无论战斗规则设置期间选择的值如何,总时间限制和每阶段时间限制都将被禁用。完成战斗后,无限时间模式将重置为服务器的默认值(可以在 config.json 的 Episode3BehaviorFlags 中设置)。
* `$dicerange [d:L-H] [1:L-H] [a1:L-H] [d1:L-H]`: 为下一场战斗设置覆盖骰子范围。规则设置菜单中的最小和最大骰子值始终适用于 ATK 骰子,但你可以使用 `d:2-4`(例如)为 DEF 骰子指定不同的范围。`1:` 覆盖适用于 2v1 游戏中的 1 人队(因此你需要在规则菜单中设置 2 人队所需的骰子范围)。你还可以使用 `a1:` 和 `d1:` 覆盖分别指定 1 人队的 ATK 和 DEF 范围。请注意,只有当所选地图或任务没有覆盖它们时,才会使用这些范围。
* `$stat `: 显示当前战斗中关于你的玩家或团队的统计信息。`` 可以是 `duration`、`fcs-destroyed`、`cards-destroyed`、`damage-given`、`damage-taken`、`opp-cards-destroyed`、`own-cards-destroyed`、`move-distance`、`cards-set`、`fcs-set`、`attack-actions-set`、`techs-set`、`assists-set`、`defenses-self`、`defenses-ally`、`cards-drawn`、`max-attack-damage`、`max-combo`、`attacks-given`、`attacks-taken`、`sc-damage`、`damage-defended` 或 `rank`。
* `$surrender`: 导致你的团队立即输掉当前的战斗。如果你的故事角色已经被击败,你无法投降 - 只有你的队友可以。
* `$saverec `: 保存上一场战斗的录像。
* `$playrec `: 播放战斗录像。此命令创建一个观察者团队,并像实时发生一样播放指定的录像。默认情况下,当观察者团队准备就绪时,播放将立即开始;你可以通过在录像名称前加上 `!` 来延迟播放以允许其他人加入。在这种情况下,在观察者团队内再次使用 `$playrec`(不带参数)将开始播放。
* 作弊模式命令
* `$cheat`(仅限非代理):启用或禁用当前游戏的作弊模式。如果禁用了作弊模式,所有其他作弊模式命令都不执行任何操作。默认情况下,新游戏中的作弊模式是关闭的,但可以启用;config.json 中有一个选项允许你完全禁用作弊模式,或者在新游戏中默认启用。代理上的作弊模式始终启用,除非整个服务器都禁用了作弊模式。
* `$infhp`: 启用或禁用无限 HP 模式。仅适用于你;不影响其他玩家。启用时,一击必杀攻击仍然会杀死你,但在大多数版本的游戏中,如果你死亡,服务器会自动复活你。无限 HP 还会自动治愈状态异常。
* `$inftp`: 启用或禁用无限 TP 模式。仅适用于你;不影响其他玩家。在 DCv1 或更早版本上不起作用。
* `$fastkill`: 启用或禁用快速击杀。仅适用于你;不影响其他玩家。启用时,服务器将在你击中任何敌人一次后将其杀死。Boss 不受快速击杀的影响。
* `$warpme `(或 `$warp `):将你自己传送到给定的楼层。
* `$warpall `: 将游戏中的所有人传送到给定的楼层。你必须是指挥官才能使用此命令,除非你在代理上。
* `$next`: 将你自己传送到下一层。
* `$item `(或 `$i `):创建一个物品。`desc` 可以是物品的描述或指定物品代码的十六进制数据字符串。物品代码为 16 个十六进制字节;必须指定至少 2 个字节,所有未指定的字节均为零。如果你在代理上,你不能使用 Blue Burst,此命令才能起作用。在游戏服务器上,此命令适用于所有版本。以下是一些说明语法的示例(不区分大小写,除了物品名称本身之外的所有内容都是可选的):
* `$item Saber +5 0/10/25/0/10`(带有特殊效果、研磨度和属性的武器)
* `$item ???? Draw Autogun`(带有特殊效果的未鉴定武器;也可以有研磨度/属性,如上所述)
* `$item SEALED J-SWORD K:2000`(带有击杀计数的武器)
* `$item ES APHEX ZALURE TWIN +200`(ES 武器必须以 "ES" 为前缀;名称在特殊效果之前)
* `$item DF FIELD +10DEF +20EVP +4`(带有 DFP 加成、EVP 加成和槽位数量的盔甲)
* `$item RED MERGE +10DFP +20EVP`(盾牌;与盔甲相同,但没有槽位数量)
* `$item Knight/Power +9`(具有特定修饰符的单元)
* `$item Knight/Power++`(具有普通修饰符的单元;++/-- 是 +4/-4,+/- 是 +2/-2)
* `$item LIMITER K:1000`(带有击杀计数的封印单元)
* `$item Tapas PB:F,G,M&Y 120% 200IQ 5/195/0/0 green`(具有 PB、同步率、IQ、属性和颜色的 Mag)
* `$item Trimate x10`(具有堆叠数量的工具)
* `$item Disk:Reverser`(没有等级的技术磁盘)
* `$item Disk:Razonde Lv.30`(带有等级的技术磁盘)
* `$item 1000 Meseta`
* `$unset `(仅限非代理):在 Episode 3 战斗中,从场上移除你的一张已设置卡牌。`` 是你屏幕上显示的已设置卡牌的索引 - 1 是你的 SC 图标旁边的卡牌,2 是 1 右边的卡牌,依此类推。这不会导致猎人方 SC 失去 HP,就像他们的物品被摧毁时通常会发生的那样。你也可以使用 `$unset 0` 摧毁设置在自己身上的辅助卡牌。
* `$dropmode [mode]`(仅限代理):如果你不在 BB 上,则更改当前游戏中物品掉的行为方式。与此命令的游戏服务器版本不同,在代理上使用此命令需要启用作弊。这通过拦截发送给指挥官和来自指挥官的掉落请求来工作。(因此,如果你是指挥官并且未在远程服务器上使用服务器掉落模式,它会影响整个游戏;否则,它仅影响由你的操作生成的物品。)`mode` 可以是 `none`(无掉落)、`default`(正常掉落)或 `proxy`(使用 newserv 的掉落表而不是远程服务器的)。如果未给出 `mode`,则告知你当前的掉落模式而不更改它。
* 外观命令
* `$event `: 在当前大厅设置当前的节日活动。节日活动记录在信息菜单的 "Using $event" 项目中。如果你在代理上,这适用于你加入的所有大厅和游戏,但只有你会看到新的活动 - 其他玩家不会。
* `$allevent `(仅限非代理):在所有大厅设置当前的节日活动。
* `$song `(仅限 Episode 3):在当前大厅播放特定的歌曲。
* 管理命令(仅限非代理)
* `$ann `: 发送公告消息。该消息作为临时屏幕文本发送给所有游戏和大厅中的所有玩家。在 BB 上,消息出现在滚动的顶栏中。
* `$ann!`, `$ann?`, `$ann?!`: 与 `$ann` 相同,但使用 `?` 时省略发送者的名字,使用 `!` 时将消息作为 Simple Mail 消息而不是屏幕文本发送。
* `$silence `: 禁言玩家(移除其聊天能力)或解除禁言。标识符可以是玩家的名字或 Guild Card 号码。
* `$kick `: 断开玩家的连接。标识符可以是玩家的名字或 Guild Card 号码。
* `$ban `: 封禁玩家。持续时间格式应为 `10m`(分钟)、`10h`(小时)、`10d`(天)、`10w`(周)、`10M`(月)或 `10y`(年)。(当然,也可以使用 10 以外的数字。)与 `$kick` 一样,标识符可以是玩家的名字或 Guild Card 号码。
### 使用 $edit
$edit 命令修改你的角色数据。此命令在 V3 (GameCube/Xbox) 上不起作用。如果你在 V1 或 V2(DC 或 PC,而非 BB)上,如果你加入游戏,你的更改将被撤销 - 要保存你的更改,请断开与大厅的连接。
某些子命令始终可用。它们是:
* `$edit mat reset power`: 清除你对力量材料的使用(仅限 BB)
* `$edit mat reset mind`: 清除你对精神材料的使用(仅限 BB)
* `$edit mat reset evade`: 清除你对回避材料的使用(仅限 BB)
* `$edit mat reset def`: 清除你对防御材料的使用(仅限 BB)
* `$edit mat reset luck`: 清除你对运气材料的使用(仅限 BB)
* `$edit mat reset hp`: 清除你对 HP 材料的使用(仅限 BB)
* `$edit mat reset tp`: 清除你对 TP 材料的使用(仅限 BB)
* `$edit mat reset all`: 清除你对所有材料的使用,HP 和 TP 除外(仅限 BB)
* `$edit mat reset every`: 清除你对所有材料的使用,包括 HP 和 TP(仅限 BB)
* `$edit namecolor AARRGGBB`: 设置你的名字颜色(AARRGGBB 以十六进制指定)
* `$edit language L`: 设置你的语言(通常仅在 BB 上有用;L 的值:J = 日语, E = 英语, G = 德语, F = 法语, S = 西班牙语, B = 简体中文, T = 繁体中文, K = 韩语)
* `$edit name NAME`: 设置你的角色名称
* `$edit npc NPC-NAME`: 在你的角色上设置或移除 NPC 皮肤(使用 `none` 移除皮肤)。NPC 名称为:
* 在除 DCv1 和早期原型之外的所有版本上:`ninja`、`rico`、`sonic`、`knuckles`、`tails`
* 在 GC、Xbox 和 BB 上:`flowen`、`elly`
* 仅在 BB 上:`momoka`、`irene`、`guild`、`nurse`
* `$edit secid SECID-NAME`: 设置你的 section ID(除非你的角色为 1 级,否则需要作弊模式)
其余子命令仅在服务器上启用作弊模式时可用。它们是:
* `$edit atp N`: 将你的 ATP 设置为 N,直到属性更新(例如通过升级)
* `$edit mst N`: 将你的 MST 设置为 N,直到属性更新
* `$edit evp N`: 将你的 EVP 设置为 N,直到属性更新
* `$edit dfp N`: 将你的 DFP 设置为 N,直到属性更新
* `$edit ata N`: 将你的 ATA 设置为 N,直到属性更新
* `$edit lck N`: 将你的 LCK 设置为 N,直到属性更新
* `$edit hp N`: 将你的 HP 设置为 N,直到属性更新
* `$edit meseta N`: 设置你物品栏中的 Meseta 数量
* `$edit exp N`: 设置你的 EXP 总量(不影响等级)
* `$edit level N`: 设置你的当前等级(重新计算属性,但不影响 EXP)
* `$edit tech TECH-NAME LEVEL`: 设置你某项技巧的等级
## REST API
newserv 有一个可选的 HTTP 服务器,它提供了一种以编程方式从服务器实时获取数据的方法。这旨在用于外部集成;例如,网站可以查询此 API 以获取当前玩家计数以显示在主页上。
HTTP 服务器默认为禁用状态,如果你想要此功能,必须在 config.json 中显式启用它。**如果启用它,请确保无法从公共 Internet 访问 HTTP 端口。** 该 API 提供了大量关于玩家和游戏的内部数据,只能由你编写的或你信任的程序访问。
要启用 HTTP 服务器,请在 config.json 的 HTTPListen 列表中添加一个端口号。HTTP 服务器将在该端口上监听。
所有返回的数据都是 JSON 编码的,并且所有请求数据(对于 POST 请求)也必须是使用 `Content-Type: application/json` 标头的 JSON 编码。
HTTP 服务器具有以下端点:
* `GET /`: 返回服务器的构建日期和修订版。
* `GET /y/data/ep3-cards`: 返回 Episode 3 卡牌定义。
* `GET /y/data/ep3-cards-trial`: 返回 Episode 3 试用版卡牌定义。
* `GET /y/data/common-tables`: 返回用于生成普通物品的参数(ItemPT 文件)。此端点返回大量数据,可能会很慢!
* `GET /y/data/rare-tables`: 返回稀有表名称列表。
* `GET /y/data/rare-tables/`(例如 `/y/data/rare-tables/rare-table-v4`):返回稀有物品表的内容。
* `GET /y/data/quests`: 返回有关所有可用任务和任务类别的元数据。
* `GET /y/data/config`: 返回服务器的配置文件。
* `GET /y/accounts`: 返回有关所有已注册帐户的信息。
* `GET /y/clients`: 返回有关游戏服务器上所有已连接客户端的信息。
* `GET /y/proxy-clients`: 返回有关代理上所有已连接客户端的信息。
* `GET /y/lobbies`: 返回有关所有大厅和游戏的信息。
* `GET /y/server`: 返回有关服务器的信息。
* `GET /y/summary`: 返回服务器状态、已连接客户端、活动游戏和代理会话的摘要。
* `WS /y/rare-drops/stream`: WebSocket 端点,在任何游戏中掉落可公告的稀有物品时发送消息。见下文。
* `POST /y/shell-exec`: 运行服务器 shell 命令。输入应为 JSON 字典,例如 `{"command": "announce hello"}`;响应将是包含 `{"result": ""}` 的 JSON 字典或 HTTP 错误。
### 稀有掉落流端点
`/y/rare-drops/stream` 端点提供了一种在例如 Discord 中实现掉落日志的方法。对于每个可公告的稀有物品,都会向此端点上的所有连接客户端发送一条消息。(可公告的稀有物品是指那些在游戏中或服务器范围内发送文本消息宣布发现的物品。)
连接后,你将收到消息 `{"ServerType": "newserv"}`。之后,当发送稀有物品公告时,你将收到如下消息:
```
{
"PlayerAccountID", 12345,
"PlayerName", "SONIC",
"PlayerVersion", "GC_V3",
"GameName", "ttf",
"GameDropMode", "SERVER_PRIVATE",
"ItemData", "03000000 00010000 00000000 (0021002C) 00000000",
"ItemDescription", "Monomate x1",
"NotifyGame", true,
"NotifyServer", false,
}
```
# 非服务器功能
newserv 有许多 CLI 选项,可用于访问游戏服务器和代理以外的功能。运行 `newserv help` 以查看选项的完整列表以及如何使用每一个。
newserv 可以转换为/转换自的数据格式为:
| 格式 | 编码/压缩操作 | 解码/解压操作 |
|-------------------------------------|---------------------------|------------------------------|
| PRS 压缩 | `compress-prs` | `decompress-prs` |
| PR2/PRC 压缩 | `compress-pr2` | `decompress-pr2` |
| BC0 压缩 | `compress-bc0` | `decompress-bc0` |
| 原始加密数据 | `encrypt-data` | `decrypt-data` |
| Episode 3 命令掩码 | `encrypt-trivial-data` | `decrypt-trivial-data` |
| 挑战模式排名文本 | `encrypt-challenge-data` | `decrypt-challenge-data` |
| PSO DC 任务文件 | None | `decode-vms` |
| PSO GC 任务文件 | None | `decode-gci` |
| 下载任务文件 | None | `decode-dlq` |
| 服务器任务文件 | `encode-qst` | `decode-qst` |
| PSO DC 存档文件 | `encrypt-vms-save` | `decrypt-vms-save` |
| PSO PC 存档文件 | `encrypt-pc-save` | `decrypt-pc-save` |
| PSO GC 存档文件 | `encrypt-gci-save` | `decrypt-gci-save` |
| PSO Xbox 存档文件 | None | `decrypt-xbox-save` |
| PSO GC 快照文件 | None | `decode-gci-snapshot` |
| 任务脚本 | `assemble-quest-script` | `disassemble-quest-script` |
| 任务地图 | None | `disassemble-quest-map` |
| AFS 归档 | None | `extract-afs` |
| BML 归档 | None | `extract-bml` |
| PPK 归档 | None | `extract-ppk` |
| GSL 归档 | `generate-gsl` | `extract-gsl` |
| GVM 纹理 | `encode-gvm` | None |
| 位图字体 | `encode-bitmap-font` | `decode-bitmap-font` |
| 文本归档 | `encode-text-archive` | `decode-text-archive` |
| Unicode 文本集 | `encode-unicode-text-set` | `decode-unicode-text-set` |
| Word Select 数据集 | None | `decode-word-select-set` |
| Set 数据表 | None | `disassemble-set-data-table` |
| 稀有物品表 | `convert-rare-item-set` | `convert-rare-item-set` |
有几个不太适合上表的操作,它们允许你做其他事情:
* 计算压缩 PRS 数据的解压大小而无需解压它(`prs-size`)
* 查找损坏的存档文件可能的 round1 或 round2 种子(`salvage-gci`)
* 运行暴力搜索以查找解密种子(`find-decryption-seed`)
* 以人类可读的方式格式化 Episode 3 游戏数据(`show-ep3-maps`、`show-ep3-cards`、`generate-ep3-cards-html`)
* 以人类可读的方式格式化 Blue Burst 战斗参数文件(`show-battle-params`)
* 将物品数据转换为人类可读的描述,反之亦然(`describe-item`)
* 显示服务器的物品和等级表(`show-item-tables`、`show-level-tables`)
* 连接到另一个 PSO 服务器并假装是客户端(`cat-client`)
* 生成或描述 DC 序列号(`generate-dc-serial-number`、`inspect-dc-serial-number`)
# Docker
Docker 目前较新,大部分情况下不受支持。但是,这里有一些在 Ubuntu Linux 上的 docker 容器中构建和运行的最佳尝试步骤。
在 Ubuntu 22.04.4 LTS 上测试。
注意:你的服务器上不能有任何除这个 docker 容器之外的东西使用 53 端口(DNS)。
安装先决条件
```
sudo apt install -y git
sudo apt install -y cmake. ## minimum version is 3.10. Check installed version with "cmake --version"
```
克隆仓库
```
cd ~
git clone https://github.com/fuzziqersoftware/newserv/
cd ~/newserv
```
构建 newserv。这需要一段时间。别忘了句点!
```
sudo docker build -t newserv .
```
创建持久化目录。假设你想将持久化数据存储在你的主目录中
```
mkdir ~/newservPersist
mkdir ~/newservPersist/players
mkdir ~/newservPersist/teams
mkdir ~/newservPersist/licenses
```
将配置文件复制到 config 目录
```
cp ~/newserv/system/config.example.json ~/newservPersist/config.json
```
编辑 config.json
```
nano ~/newservPersist/config.json
```
专业提示:
将 "LocalAddress" 设置为服务器的静态 LAN IP 地址。如果你的服务器 LAN IP 是 "192.168.0.10":
"LocalAddress": "192.168.0.10",
将 "ExternalAddress" 设置为网络的 WAN IP 地址。如果你的 WAN IP 是 "8.8.8.8":
"ExternalAddress": "8.8.8.8",
对于 Dolphin > 设置。将 SP1 设置为 "Broadband Adapter (HLE)" 点击旁边的 [...],并将 DNS 设置为服务器的 IP 地址。然后启动游戏。如果游戏正在运行,更改将不会生效。
Docker 运行。请记住将 /home/changeme/newservPersist 更改为你的持久化目录。不要使用诸如 '~' 之类的别名
```
docker run --name newserv -p 53:53/udp -p 5100:5100 -p 5110:5110 -p 5111:5111 -p 5112:5112 -p 9064:9064 -p 9100:9100 -p 9103:9103 -p 9300:9300 -p 11000:11000 -p 12000:12000 -p 12004:12004 -p 12005:12005 -v /etc/localtime:/etc/localtime:ro -v /home/changeme/newservPersist/config.json:/newserv/system/config.json -v /home/changeme/newservPersist/players:/newserv/system/players -v /home/changeme/newservPersist/teams:/newserv/system/teams -v /home/changeme/newservPersist/licenses:/newserv/system/licenses --restart no newserv:latest
```
Docker 运行主机网络模式。请记住将 /home/changeme/newservPersist 更改为你的持久化目录。不要使用诸如 '~' 之类的别名
```
docker run --net host --name newserv -v /etc/localtime:/etc/localtime:ro -v /home/changeme/newservPersist/config.json:/newserv/system/config.json -v /home/changeme/newservPersist/players:/newserv/system/players -v /home/changeme/newservPersist/teams:/newserv/system/teams -v /home/changeme/newservPersist/licenses:/newserv/system/licenses --restart no newserv:latest
```
Docker compose。请记住将 /home/changeme/newservPersist 更改为你的持久化目录。不要使用诸如 '~' 之类的别名
```
name: psonewserv
services:
newserv:
container_name: newserv
ports:
- 53:53/udp
- 5100:5100
- 5110:5110
- 5111:5111
- 5112:5112
- 9064:9064
- 9100:9100
- 9103:9103
- 9300:9300
- 11000:11000
- 12000:12000
- 12004:12004
- 12005:12005
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/changeme/newservPersist/config.json:/newserv/system/config.json
- /home/changeme/newservPersist/players:/newserv/system/players
- /home/changeme/newservPersist/teams:/newserv/system/teams
- /home/changeme/newservPersist/licenses:/newserv/system/licenses
restart: no ## Set to whatever you want.
image: newserv:latest
```
Docker compose 主机网络模式。请记住将 /home/changeme/newservPersist 更改为你的持久化目录。不要使用诸如 '~' 之类的别名
```
name: psonewserv
services:
newserv:
container_name: newserv
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/changeme/newservPersist/config.json:/newserv/system/config.json
- /home/changeme/newservPersist/players:/newserv/system/players
- /home/changeme/newservPersist/teams:/newserv/system/teams
- /home/changeme/newservPersist/licenses:/newserv/system/licenses
restart: no ## Set to whatever you want.
network_mode: host
image: newserv:latest
```
newserv 是一个针对 Phantasy Star Online (PSO) 的游戏服务器、代理和逆向工程工具。**要快速上手使用 newserv,只需阅读[服务器设置](#server-setup)和[如何连接](#how-to-connect)部分。**
本项目包含了很久以前社区逆向工程的代码,此后已被包含在许多项目中。它还包含来自 Phantasy Star Online 本身的一些游戏数据,这些数据最初是由 Sega 创建的。
如果您发现错误或有功能请求,请随时提交 GitHub issues。我想让服务器尽可能稳定和完整,但我不能保证我会及时回复问题,因为这是一个主要是为了逆向工程的乐趣而进行的个人项目。如果您想自己为 newserv 做贡献,也欢迎提交 pull requests。
请参阅 TODO.md 以获取我整理的已知问题和未来工作列表,或访问 GitHub issue tracker 查看社区提交的问题和请求。
**目录**
* 背景
* [历史](#history)
* [其他服务器项目](#other-server-projects)
* [在其他项目中使用 newserv](#using-newserv-in-other-projects)
* [为 newserv 做贡献](#contributing-to-newserv)
* [兼容性](#compatibility)
* 设置
* [服务器设置](#server-setup)
* [PC 和 BB 的客户端补丁目录](#client-patch-directories)
* [如何连接](#how-to-connect)
* 功能与配置
* [用户账户](#user-accounts)
* [安装任务](#installing-quests)
* [物品表和掉落模式](#item-tables-and-drop-modes)
* [跨版本游戏](#cross-version-play)
* [服务器端存档](#server-side-saves)
* [Episode 3 功能](#episode-3-features)
* [内存补丁、客户端函数和 DOL 文件](#memory-patches-and-client-functions)
* [将 newserv 用作代理](#using-newserv-as-a-proxy)
* [聊天命令](#chat-commands)
* [REST API](#rest-api)
* [非服务器功能](#non-server-features)
# 历史
这个项目的历史本质上反映了从我刚开始这个爱好直到现在我作为一名软件工程师的发展历程。如果你不关心这个故事,请跳到下面的“兼容性”或“设置”部分。
我最初购买 PSO GC 是因为我听说了 PSUL,并想在 GameCube 上运行自制软件。这条路径最终导致了 [GCARS-CS](https://github.com/fuzziqersoftware/gcars-cs),但那是另一个故事了。
在玩了一段时间 PSO(包括离线和在线)后,我在 2003 年的某个时候写了一个名为 Khyps 的代理。那是回到官方 Sega 服务器的时代,漏洞没有被及时解决或根本没有解决。使用自己的代理或 Action Replay 代码(这是一个以后再讲的故事)的恶意玩家发送服务器会盲目转发的无效命令,并导致接收客户端崩溃,这种情况很常见。这些崩溃不仅仅是带来不便;它们还可能损坏你的存档数据,摧毁你可能投入在寻找物品和升级角色上的数小时工作。
有一段时间,使用代理上网基本上是必须的,这样代理才能阻止这些无效命令。Khyps 的设计主要考虑了这一功能,尽管它也实现了一些方便的作弊功能,比如给自己或其他玩家无限 HP 的能力,以及允许你在不使用游戏内传送装置的情况下传送到不同的地方。
在 Khyps 之后,我接受了编写服务器的更大挑战,这导致了 2005 年某个时候 Khyller 的诞生。这是我编写的第一个任何类型的服务器。这个项目最终演变成一个支持我有权访问的游戏的所有版本的全功能环境——当时是 PC、GC 和 BB。(然而,通过阅读古老的源文件,我怀疑 Khyller 的 BB 支持非常漏洞百出。)随着 Khyller 的发展,代码变得越来越笨重,充斥着我从未清理过的调试垃圾和我多年来习得的奇怪编码模式。我对 C++ 语言的理解也是可悲的不完整(与现在相反,现在它仍然不完整,但不是可悲的不完整),这导致 Khyller 本质上是一个包含几个类的 C 项目。
在 2006 年或 2007 年的某个时候,我放弃了 Khyller 并从头开始重建了整个项目,结果就是 Aeon。Aeon 的代码比 Khyller 干净得多,但仍然相当难以处理,而且它缺少我最初编写的一些更深奥的功能(例如,将任何任务转换为下载任务的能力)。此外,代码仍然有一些稳定性问题……事实证明 Aeon 的并发原语根本就是不正确的。我在上任何真正的计算机工程课之前自己推导了互斥锁的概念,但实现不正确。我使竞争窗口尽可能小,但 Aeon 在看似正常运行几天后仍会随机崩溃。
在 Aeon 出现之初,它也被称为 newserv,你可能会在网上找到一些文件名像 `newserv-b3.zip` 这样的测试版。我发布了测试版 1、2 和 3,然后发布了测试版 5 的全部源代码,并在上大学时停止了该项目的工作。这大概是我从主要在 Windows 上编写软件转向主要在 macOS 和 Linux 上编写软件的时候,所以 Aeon beta 5 是我编写的最后一个专门针对 Windows 的服务器。(你现在看到的 newserv 很难在 Windows 上编译,但确实可以工作。)
在 long 时间没有接触 PSO 以及在技术能力上有了很多专业和个人发展之后,2018 年 10 月的某个时候,我在阅读我的旧代码档案时回忆起了往事。当我遇到 Aeon 时,不知何故受到了启发,我花了一个周末和几个晚上的时间再次重写了整个项目,清理了我十一年前使用的古老模式,用简单的 STL 容器替换了整个模块,并取消了更多的支持文件,转而使用配置自动检测。代码现在已经足够现代和稳定,我不再为它的存在感到尴尬,就像我对 Aeon beta 5 的源代码和我的 Khyller 档案(幸好没有其他人见过)感到尴尬一样。
## 其他服务器项目
独立于本项目,还有许多其他的 PSO 服务器。我所知道的(或曾经)公开的服务器按大致的时间顺序列在这里:
* (2000 年代早期) **[Schtserv](https://schtserv.com/)**:第一个公共访问的 PSO 服务器,由 Schthack 用 Delphi 编写。Schtserv 是唯一另一个支持 Episode 3 的非官方服务器,其实现基于 newserv(而 newserv 又基于 Sega 的)。
* (2005) **Khyller**:我早期尝试支持 PSO PC、GC 和 BB 的产物。详见上文。
* (2006) **Aeon**:我的第二次尝试。比 Khyller 好,但仍然不可靠。
* (2008) **Tethealla**:一个相当广泛的 PSOBB 实现,由 Sodaboy 用 C 语言编写。Tethealla 的公开版本已被[正式弃用](https://www.pioneer2.net/community/threads/tethealla-server-forums-removal.26365/),因为它现在已有 15 年以上的历史,但闭源开发仍在继续。[Ephinea](https://ephinea.pioneer2.net/) 是该项目的延续。其他几个现代 PSOBB 服务器也是 Tethealla 最初公开版本的分支。
* (2008) **[Sylverant](https://sylverant.net/)** [(源码)](https://sourceforge.net/projects/sylverant/):第二个公共访问的 PSO 服务器,由 BlueCrab 用 C 语言编写。
* (2015) **[Archon](https://github.com/dcrodman/archon)**:一个由 Drew Rodman 用 Go 语言编写的 PSOBB 服务器。
* (2015) **[Idola](https://github.com/HybridEidolon/idolapsoserv)**:一个由 HybridEidolon 用 Rust 语言编写的 PSOBB 服务器。功能状态未知;该项目已存档。
* (2017) **[Aselia](https://github.com/Solybum/Aselia)**:一个由 Soly 用 C# 编写的 PSOBB 服务器。看起来这个项目曾计划在某个时候开源,但这(尚)未发生。
* (2018) **newserv**:就是本项目。
* (2019) **[Mechonis](https://gitlab.com/sora3087/mechonis)**:一个由 TrueVision 用 TypeScript 编写的具有微服务架构的 PSOBB 服务器。
* (2020) **[Booma.Server](https://github.com/HelloKitty/Booma.Server)**:一个由 Glader 在 Soly 的帮助下用 C# 编写的 PSOBB 服务器。
* (2021) **[Phantasmal World](https://github.com/DaanVandenBosch/phantasmal-world)**:一套 PSO 工具,包括基于 Web 的模型查看器和任务构建器,以及一个 PSO 服务器,由 Daan Vanden Bosch 编写。
* (2021) **[Elseware](http://git.sharnoth.com/jake/elseware)**:一个由 Jake 用 Rust 语言编写的 PSOBB 服务器。
## 在其他项目中使用 newserv
您可以在您自己的开源项目中自由使用 newserv 的代码;唯一的条件是,如果您使用 newserv 的代码,您的项目中必须包含 LICENSE 文件的内容。您的项目不必也使用 MIT 许可证;您可以使用您想要的任何许可证。
如果您想在您的项目中使用 newserv 的部分内容,有两种简单的方法可以做到这一点并遵守许可规定:
* 如果您使用 newserv 的大量代码,您可以将 newserv 的 LICENSE 文件的副本放在您的存储库中,与您自己的许可证文件并列,或者将 newserv 许可证的内容包含在您自己的许可证文件中。
* 如果您只使用 newserv 的几个文件,您可以将 LICENSE 文件的内容复制并粘贴到每个复制文件开头的注释中。
一些更有可能有用的文件是:
* **src/CommandFormats.hh**: 所有已知版本的游戏中使用的所有网络命令及其格式的完整列表
* **src/CommonItemSet.hh/cc**: ItemPT 文件、商店定义文件和 tekker 调整表的格式
* **src/DCSerialNumbers.hh/cc**: PSO DC 序列号验证算法和序列号生成器
* **src/ItemData.hh**: 物品格式参考
* **src/ItemCreator.hh/cc**: 来自 Episodes 1&2 的逆向工程物品生成器(用于所有版本)
* **src/ItemParameterTable.hh**: ItemPMT.prs 中许多结构的格式
* **src/Map.hh/cc**: 地图文件(.dat/.evt)结构、对象/敌人类型和参数列表,以及逆向工程的挑战模式随机敌人生成算法
* **src/QuestScript.cc**: 所有版本上所有任务操作码的完整列表,以及它们的参数和行为
* **src/RareItemSet.hh/cc**: ItemRT 文件(稀有物品掉落表)的格式
* **src/SaveFileFormats.hh**: 所有版本的存档文件结构定义
* **src/Episode3/DataIndexes.hh**: Episode 3 文件结构,包括卡片定义格式和地图/任务格式
* **system/item-tables/names-v4.json**: 所有物品的名称,按 data1 的前 3 个字节索引
## 为 newserv 做贡献
本项目的目标是:
* 构建稳定、可扩展的 PSO 服务器软件,包括所有原版功能以及可选的现代便利设施、功能和作弊。
* 记录 PSO 网络协议、文件格式和游戏机制的内部细节。这主要通过代码中的注释来完成。
这是一个个人项目;没有官方开发团队、官方网站或官方 newserv 实例。欢迎提交 issues 和 pull requests,但请仅添加您创建的、已经公开的或您有权公开发布的内容(例如任务或补丁)。
# 兼容性
newserv 支持所有已知的 PSO 版本,包括各种开发原型。此表列出了 newserv 支持的所有版本。(NTE 代表网络试玩版;GameCube 测试版被称为试玩版,但为了一致性,我们仍然使用 NTE 缩写。)
| 版本 | 大厅 | 游戏 | 代理 |
|-----------------|----------|----------|----------|
| DC NTE | 是 | 是 | 是 |
| DC 11/2000 | 是 | 是 | 是 |
| DC 12/2000 | 是 | 是 | 是 |
| DC 01/2001 | 是 | 是 | 是 |
| DC V1 | 是 | 是 | 是 |
| DC 08/2001 | 是 | 是 | 是 |
| DC V2 | 是 | 是 | 是 |
| PC NTE | 是 (1) | 是 | 是 |
| PC | 是 | 是 | 是 |
| GC Ep1&2 NTE | 是 | 是 | 是 |
| GC Ep1&2 | 是 | 是 | 是 |
| GC Ep1&2 Plus | 是 | 是 | 是 |
| GC Ep3 NTE | 是 | 是 (2) | 是 |
| GC Ep3 | 是 | 是 | 是 |
| Xbox Ep1&2 Beta | 是 (3) | 是 (3) | 是 (3) |
| Xbox Ep1&2 | 是 (3) | 是 (3) | 是 (3) |
| BB (vanilla) | 是 | 是 | 是 |
| BB (Tethealla) | 是 | | 是 |
*注意:*
1. *这是唯一一个没有任何方法识别玩家账户的 PSO 版本——没有序列号或用户名。因此,必须在 config.json 中启用 AllowUnregisteredUsers 以支持 PC NTE,并且 PC NTE 玩家每次连接时都会收到一个随机的公会卡号。为防止滥用,可以在 config.json 中禁用 PC NTE 支持。*
2. *Episode 3 NTE 战斗未经充分测试;某些功能可能无法工作。有关 NTE 和最终版本之间已知差异的列表,请参阅 notes/ep3-nte-differences.txt。NTE 和非 NTE 玩家不能互相战斗。*
3. *PSO Xbox 通过 Xbox Live 连接,因此您无法轻松为此版本的游戏托管私人服务器。请参阅[如何连接](#pso-xbox)部分。*
# 设置
## 服务器设置
目前 newserv 可在 macOS、Windows 和 Ubuntu Linux 上运行。它很可能也能在其他 Linux 发行版上运行。
### Windows/macOS
1. 从[发布页面](https://github.com/fuzziqersoftware/newserv/releases)下载最新的 release.zip 文件。
2. 将压缩包的内容解压到您计算机上的某个位置。
3. 进入 system/ 文件夹,在文本编辑器中打开 config.json,并根据您的喜好进行编辑。文件中有注释描述了所有选项的作用。如果您想要默认行为,大多数选项可以保留不变,但在 Windows 上,您必须更改 LocalAddress 和 ExternalAddress。
4. (可选)如果您计划在 newserv 上玩 Blue Burst,请设置补丁目录。有关详细信息,请参阅[客户端补丁目录](#client-patch-directories)。
5. 运行 newserv 可执行文件。
### Linux
目前没有 Linux 的预编译版本。要在 Linux 上运行 newserv,您必须从源代码构建它——请参阅下面的部分。
### 从源代码构建
要在 macOS 或 Linux 上构建:
1. 安装您的平台所需的依赖项:
* macOS: `brew install cmake asio libiconv`
* Linux: `sudo apt-get install cmake libasio-dev`(或使用您的 Linux 发行版的包管理器)
2. 构建并安装 [phosg](https://github.com/fuzziqersoftware/phosg) 和 [resource_dasm](https://github.com/fuzziqersoftware/resource_dasm)。
3. 在 newserv 目录中运行 `cmake . && make`。
构建 newserv 后,根据需要编辑 system/config.example.json **并将其重命名为 system/config.json**(请注意,预编译版本不需要此步骤),如果您计划玩 Blue Burst,请设置[客户端补丁目录](#client-patch-directories),然后在 newserv 的目录中运行 `./newserv`。
服务器有一个交互式 shell,可用于进行更改,例如管理用户账户、更新服务器配置、管理 Episode 3 比赛等。输入 `help` 并按 Enter 查看所有命令。
在 Linux 和 macOS 上,服务器也响应 SIGUSR1 和 SIGUSR2。SIGUSR1 执行相当于 shell 的 `reload config` 命令,该命令重新加载 config.json 但不重新加载任何依赖文件(因此任务、Episode 3 地图等将不会被重新加载)。SIGUSR2 执行相当于 shell 的 `reload all` 命令,该命令重新加载所有内容。
要以其他方式使用 newserv(例如用于转换数据),请参阅本文档的末尾。
### 从源代码构建
当前版本的 newserv 是在 macOS 构建机器上使用 mingw-w64 交叉编译的,并手动安装了必要的库。设置这样的构建环境很繁琐,不推荐;建议直接使用发布版本。
以下是 Windows 构建过程的粗略大纲。只有在您熟悉设置构建环境并且能够处理沿途可能遇到的问题时,才应自行尝试此操作。
1. 安装最新版本的 MinGW 和 CMake。
2. 将 zlib、libiconv、asio、phosg 和 resource_dasm 构建并安装到您的 MinGW 环境中。
3. 启用符号链接克隆 newserv 存储库:`git clone -c core.symlinks=true https://github.com/fuzziqersoftware/newserv.git`
4. 通过 CMake 构建 newserv。
## 客户端补丁目录
newserv 为 PSO PC 和 PSO BB 游戏数据实现了补丁服务器。您放在 system/patch-bb 或 system/patch-pc 目录中的任何文件或目录在连接到补丁服务器时都会同步到客户端。
对于 Blue Burst 设置,以下内容对于流畅的体验是强制性的:
1. 浏览到您选择的客户端的数据目录。
2. 复制所有 `map_*.dat` 文件、`map_*.evt`、`unitxt_*` 文件以及 `data.gsl` 文件,并将它们放在 `system/patch-bb/data` 中。
3. 如果您使用的是 Tethealla 客户端的游戏文件,请在 system/patch-bb/data 中制作 `unitxt_j.prs` 的副本并将其命名为 `unitxt_e.prs`。(如果 `unitxt_e.prs` 已经存在,请用复制的文件替换它。)
如果您没有 BB 客户端,或者您使用的是来自其他来源的 Tethealla 客户端,可以在这里找到与 newserv 兼容的 Tethealla 客户端:[英文](https://web.archive.org/web/20240402011115/https://ragol.org/files/bb/TethVer12513_English.zip)/[日文](https://web.archive.org/web/20240402013127/https://ragol.org/files/bb/TethVer12513_Japanese.zip)。这些客户端会自动连接到 127.0.0.1 (localhost)。
对于 BB 客户端,newserv 从补丁数据中读取一些文件以实现游戏逻辑,因此某些游戏文件在服务器和客户端之间同步非常重要。newserv 在 system/maps/bb-v4 目录中包含这些文件的默认值,但如果这些文件与客户端的文件副本不匹配,游戏中将会发生奇怪的行为。
为了使服务器启动更快,newserv 会缓存补丁目录中文件的修改时间、大小和校验和。如果补丁服务器似乎出现异常行为,请尝试删除相关补丁目录中的 .metadata-cache.json 文件,以强制 newserv 重新计算所有校验和。此外,在校验和被缓存的情况下,newserv 可能实际上不会加载补丁文件的数据,直到客户端需要它为止。因此,在 newserv 运行时修改补丁树的任何部分都可能导致客户端看到它的不一致视图。
补丁目录内容缓存在内存中。如果您更改了这些文件,可以在交互式 shell 中运行 `reload patch-indexes` 以使更改生效,而无需重启服务器。
## 如何连接
### PSO DC
根据您拥有的 PSO DC 版本,连接到 newserv 实例的说明会有所不同。
如果您拥有 NTE、USv1、EUv1 或 EUv2 以及宽带适配器,请在运行 newserv 的 DNS 服务器的情况下,将宽带 DNS 地址编辑为 newserv 的 IP 地址。否则,必须修补光盘或使用 codebreaker 代码来移除 Hunter License 服务器检查和/或将 PSO 重定向到 newserv 实例。修补光盘或创建 codebreaker 代码超出了本文档的范围。
### Flycast 上的 PSO DC
如果您正在模拟 PSO DC,通过在 Flycast 的 `emu.cfg` 文件中的 `[network]` 下设置以下选项,NTE、USv1、EUv1 和 EUv2 版本将连接到 newserv:
- DNS = 您的 newserv 的服务器地址(newserv 的 DNS 服务器必须在 53 端口运行)
- EmulateBBA = yes
- Enable = yes
还需要将任何 DNS 信息保存到 Dreamcast 的闪存中才能使用 BBA——最简单的方法是在 USv2 中使用网站选项,然后选择保存到闪存选项。
如果服务器运行在与 Flycast 相同的机器上,这可能不起作用,即使您将 Flycast 的 DNS 查询指向您的本地 IP 地址(而不是 127.0.0.1)。在这种情况下,您可以修改内存中加载的可执行文件,使其连接到您想要的任何地方。newserv 附带了一个脚本,可以在 macOS 上执行此操作;类似的技巧可以在 Linux 上使用 scanmem 或在 Windows 上使用 Cheat Engine 手动完成。要使用该脚本,请执行以下操作:
1. 构建并安装 [memwatch](https://github.com/fuzziqersoftware/memwatch)。
2. 启动 Flycast 并运行 PSO。(您必须在运行脚本之前启动 PSO;如果在加载游戏之前运行脚本,它将无法工作。)
3. 运行 `sudo patch_flycast_memory.py 标签:Bash脚本, C++, DOL文件, MMO工具, Phantasy Star Online, REST API, SEGA, 云资产清单, 多人在线游戏, 开源游戏项目, 数据擦除, 梦幻之星在线, 游戏代理, 游戏服务器, 游戏私服, 网络协议分析, 网络封包, 记忆体修改, 跨版本游戏, 逆向工程