![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
SAMP 迁移到 openmp 完整指南 + pawn 编译报错全解析 - 打印版本 +- samp | open.mp 联机社区论坛 (https://open-mp.cn) +-- 板块: SA-MP (https://open-mp.cn/forumdisplay.php?fid=12) +--- 板块: 教程 (https://open-mp.cn/forumdisplay.php?fid=17) +--- 主题: SAMP 迁移到 openmp 完整指南 + pawn 编译报错全解析 (/showthread.php?tid=18) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SAMP 迁移到 openmp 完整指南 + pawn 编译报错全解析 - 小鸟unsigned - 03-20-2026 SAMP 迁移到 openmp 完整指南 + pawn 编译报错全解析引用:本篇适合: 第一部分:迁移步骤第一步:下载 open.mp 服务端前往 https://github.com/openmultiplayer/open.mp/releases 下载最新版本。
第二步:解压目录结构 代码: omp-server/第三步:放置脚本插件文件
引用:YSI 用户:需要升级到 YSI-5.x,YSI-4 与 open.mp 不兼容。 引用:FCNPC 用户:FCNPC 插件已被官方 open.mp NPC 组件取代,转换代码即可使用。 引用:YSF 用户:open.mp 已内置了大多数 YSF 的原生函数,不再需要 YSF。 注意:有些插件需要放进 components/ 而不是 plugins/,具体查阅以下清单:常见插件
以上资料来源个人经验和 open.mp/docs/server/Installation 第四步:修改 #include打开你的 .pwn 文件,把第一行:代码: #include <a_samp>改为: 代码: #include <open.mp>然后按 F5 编译。 第五步:配置 config.json用记事本打开 config.json,按需修改:加载主图: 代码: "main_scripts": [加载插件: 代码: "legacy_plugins": [加载过滤脚本: 代码: "side_scripts": [设置 RCON 密码: 代码: "rcon": {引用:如何把旧的 第六步:启动服务器Windows: 双击 omp-server.exeLinux: 代码: chmod +x omp-server第二部分:SA-MP 到 open.mp 的变化有以下几个变化 变更一:拼写统一为英式英语open.mp 将所有函数名统一为英式拼写, Color 改为 Colour,例如:代码: // SA-MP 写法(会报 warning)批量替换方法:在你的编辑器里按 Ctrl+H,把所有 .....Color 替换为 .....Colour。如果不想逐个修改,可以在 include 顶部加上: 代码: #define MIXED_SPELLINGS变更二:GetPlayerPoolSize 等函数已移除GetPlayerPoolSize()、GetVehiclePoolSize()、GetActorPoolSize() 这三个函数在 open.mp 中已被移除,因为它们本身就存在 bug(返回的是最高 ID 而不是数量,而且没有玩家时会返回错误数据)。代码: // 错误:这些函数不存在了同理:
变更三:死亡不再自动扣 100 元SA-MP 中玩家死亡后会自动扣除 100 元(住院费)。open.mp 移除了这个机制,让脚本自己管理金钱。 如果你的脚本之前为了「修复」这个扣钱机制,在 OnPlayerDeath 或 OnPlayerSpawn 里手动加了 GivePlayerMoney(playerid, 100),现在应该删掉这行,否则玩家死亡后反而会多 100 元。如果你的脚本确实依赖这个「死亡扣钱」功能,在 OnPlayerDeath 里手动加上:代码: public OnPlayerDeath(playerid, killerid, WEAPON:reason)变更四:HideMenuForPlayer 行为修正SA-MP 中 HideMenuForPlayer 会忽略你传入的菜单 ID,直接关掉玩家当前打开的任意菜单。open.mp 修正了这个行为,现在它只会关闭你指定的那个菜单。 代码: // SA-MP 的老写法(在 open.mp 里可能不按预期工作)变更五:SetPlayerAttachedObject 不再跨模式保留SA-MP 中玩家身上的附加物件(attached objects)在游戏模式重启后仍然保留。open.mp 修正了这个行为,重启后附加物件会消失。 如果你需要在模式重启后保留玩家的附加物件,需要在 OnPlayerConnect 里重新为他设置。变更六:GameText 样式统一(不再渐变)SA-MP 中有些 GameText 样式会闪烁、有些会忽略时间参数。open.mp 统一用 TextDraw 重新实现了这些样式,外观相同但不再渐变。如果你的玩家反馈 GameText 显示效果有变化,这是正常现象。 自动升级工具open.mp 提供了一个自动升级工具,可以批量修复旧代码中的 tag 问题、const 问题和拼写问题:
建议先用工具跑一遍,再手动处理剩余的报错。 第三部分:编译错误与警告完全手册编译器报的信息分两种:
常见 Error(错误)error 001: expected token含义:期望某个符号但没找到,通常是缺少分号、括号不匹配。 代码: // 错误:缺少分号代码: // 错误:括号不匹配error 017: undefined symbol "xxx"含义:用了一个没有定义过的变量、函数或常量。 最常见的三种原因: 1. 名字拼写错误 代码: // 错误2. SetTimerEx 的目标函数忘记 forward 代码: // 错误:没有 forward,运行时找不到函数3. 变量在使用之前没有声明 代码: // 错误:先用再声明error 021: symbol already defined "xxx"含义:同一个名字被定义了两次。 代码: // 错误:同名变量重复声明也可能是 .inc 文件被 #include 了两次,导致里面的函数被重复引入。解决方法:在每个 .inc 文件顶部加防重复引入守卫:代码: #if defined _MY_INCerror 025: function heading differs from prototype含义: forward 声明的参数和实际 public 函数的参数不一致,或者参数类型不匹配。代码: // 错误:forward 和 public 参数不一致open.mp 特别常见的情况是回调参数的 tag 不匹配: 代码: // 错误(SA-MP 写法)代码: // 错误error 010: invalid function or declaration含义:函数定义或声明的语法写错了。 代码: // 错误:函数名后面缺括号error 029: invalid expression, assumed zero含义:表达式写法不合法,通常是运算符用错或者判断写法有问题。 代码: // 错误:判断用了单等号(赋值)而不是双等号(比较)error 035: argument type mismatch (argument N)含义:函数调用时,第 N 个参数的类型与函数期望的类型不符。 代码: // 错误:SetPlayerHealth 需要 Float,传了整数代码: // 错误:传了字符串给需要整数的参数error 047: array sizes do not match含义:把一个数组赋值给另一个数组,但两者大小不一样。 代码: new a[10];error 004: function not implemented含义:只有 forward 声明,没有对应的 public 函数体。代码: // 错误:只 forward 了,没有写函数体常见 Warning(警告)warning 213: tag mismatch含义:变量或参数的 tag(类型标签)不匹配。这是迁移到 open.mp 最常见的警告。 open.mp 为很多函数参数增加了 tag,让编译器能检查你传的值是否合理: 代码: // 警告:传了普通整数而不是 bool代码: // 警告:传了数字而不是枚举值如果暂时不想处理这些警告,可以在顶部加: 代码: #define NO_TAGSwarning 234: function is deprecated含义:你用的函数已经过时,open.mp 建议换用新的写法。 TextDrawColor → TextDrawColour 代码: TextDrawColor(textid, 0xFFFFFFFF); // 警告GetPlayerPoolSize / GetVehiclePoolSize / GetActorPoolSize 代码: GetPlayerPoolSize() // 警告:已移除SHA256_PassHash(不安全的密码哈希) 代码: SHA256_PassHash(...); // 警告:SHA-256 不安全warning 214 / 239: const 相关警告含义:把字符串或数组传给没有 const 修饰的参数,或者反过来。代码: // 警告:参数应该是 constwarning 203: symbol is never used含义:你声明了一个变量或函数,但从来没有使用过。 代码: // 警告:声明了但没用解决方法:删掉没用的变量/函数,或者用 stock 修饰函数告诉编译器「不用也不要警告」:代码: stock MyMaybeUnusedFunction()warning 204: symbol is assigned a value that is never used含义:给变量赋值了,但这个值从来没被读取。 代码: new iResult = SomeFunction(); // 警告:iResult 赋了值但后面没用到通常意味着这行代码没有实际效果,检查是否逻辑有误。 warning 211: possibly unintended assignment含义:在 if 条件里用了单等号 =,可能是误把赋值写成了比较。代码: // 警告:这是赋值,不是比较,结果永远为 truewarning 219: local variable shadows a variable at a higher level含义:在内层作用域声明了一个和外层同名的变量,内层的「遮住」了外层的,容易引发逻辑混乱。 代码: new gold = 100; // 外层解决方法:给内层变量换个名字,或者直接用外层变量。 warning 225: unreachable code含义:有一段代码永远不会被执行到,通常是 return 后面还有代码。代码: MyFunction()warning 209: function should return a value含义:函数应该有返回值,但某个分支没有 return。代码: // 警告:else 分支没有 returnwarning 202: number of arguments does not match definition含义:调用函数时传入的参数数量和函数定义不一致。 代码: // 函数定义需要 2 个参数运行时报错(服务器控制台)这些不是编译错误,而是服务器运行时打印在控制台的提示。 Couldn't announce legacy network to open.mp list代码: [Info] Couldn't announce legacy network to open.mp list.含义:服务器无法被 open.mp 的服务器列表访问到。 原因:
影响:不影响服务器正常运行,玩家仍然可以通过 IP 直连,只是不会显示在公开服务器列表里。 Insufficient specifiers given to format代码: [Warning] Insufficient specifiers given to `format`: "?" < 1含义: format 函数里,格式字符串中的占位符数量少于你传入的参数数量。代码: new str[32];有用的资源
延伸阅读
如果您在运行服务器时仍有问题,请加入官方的 open.mp Discord 服务器:https://discord.gg/samp 在 #openmp-support 频道提问。 或者在我们的社区群求助: 673335567 #GTA# #圣安地列斯# #侠盗猎车手# #圣安地列斯联机# #samp# #gta联机# #gtasa联机# #openmp# #omp# #open.mp# #gtasa# |