<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>open.mp Blog</title>
        <link>https://omp.itsneufox.com/zh-CN/blog</link>
        <description>open.mp Blog</description>
        <lastBuildDate>Wed, 12 Feb 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <item>
            <title><![CDATA[Windows Defender 对启动器的误报问题]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/launcher-false-positive</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/launcher-false-positive</guid>
            <pubDate>Wed, 12 Feb 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[部分用户报告，Windows Defender 将 open.mp 启动器误报为木马/病毒。这是一个误报，该启动器完全可以安全使用。]]></description>
            <content:encoded><![CDATA[<p>部分用户报告，<strong>Windows Defender 将 open.mp 启动器误报为木马/病毒</strong>。这是一个<strong>误报</strong>，该启动器完全可以安全使用。</p>
<p>启动器是<strong>完全开源的</strong>，你可以自行审查或构建代码：
<a href="https://github.com/openmultiplayer/launcher" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/launcher</a></p>
<p>我们<strong>已经在着手修复这个问题</strong>，以确保未来的版本不会被误报。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="当前应对措施">当前应对措施<a href="https://omp.itsneufox.com/zh-CN/blog/launcher-false-positive#%E5%BD%93%E5%89%8D%E5%BA%94%E5%AF%B9%E6%8E%AA%E6%96%BD" class="hash-link" aria-label="当前应对措施的直接链接" title="当前应对措施的直接链接" translate="no">​</a></h2>
<p>在微软更新其检测特征库之前，你可以将启动器文件夹添加为 Windows Defender 的排除项：</p>
<ol>
<li class="">打开 <strong>Windows 安全中心</strong>（在开始菜单中搜索）</li>
<li class="">进入 <strong>病毒和威胁防护</strong></li>
<li class="">在 <strong>病毒和威胁防护设置</strong> 下，点击 <strong>管理设置</strong></li>
<li class="">向下滚动到 <strong>排除项</strong> 并点击 <strong>添加或删除排除项</strong></li>
<li class="">点击 <strong>添加排除项</strong> → <strong>文件夹</strong></li>
<li class="">选择你的 <strong>open.mp 启动器安装文件夹</strong> 并确认</li>
<li class="">关闭并重新打开启动器</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="注意事项">注意事项<a href="https://omp.itsneufox.com/zh-CN/blog/launcher-false-positive#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9" class="hash-link" aria-label="注意事项的直接链接" title="注意事项的直接链接" translate="no">​</a></h3>
<ul>
<li class="">请排除<strong>整个启动器文件夹</strong>，而不是单个文件，因为文件的哈希值会随着更新而改变。</li>
<li class="">如果在添加排除项后 Defender 仍然发出警告，请完全关闭启动器，再次核对排除路径，然后重试。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="为什么会发生这种情况">为什么会发生这种情况？<a href="https://omp.itsneufox.com/zh-CN/blog/launcher-false-positive#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E5%8F%91%E7%94%9F%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5" class="hash-link" aria-label="为什么会发生这种情况？的直接链接" title="为什么会发生这种情况？的直接链接" translate="no">​</a></h2>
<p>误报在游戏相关软件中很常见。反病毒软件的启发式检测可能会将与游戏进程交互的合法程序标记为威胁。我们正在与微软合作，以使启动器被正确加入白名单。</p>
<p>仍有疑问？请通过我们的 <a href="https://discord.gg/samp" target="_blank" rel="noopener noreferrer" class="">Discord</a> 联系我们。</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[迁移至 open.mp]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/porting</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/porting</guid>
            <pubDate>Wed, 06 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[SA:MP 已停滞多年，毫无更新，且需要大量变通方案才能维持运行。open.mp 改变了这一现状——它是一个完整的重写版本，修复了长期存在的问题，改进了脚本功能，并移除了旧的限制，同时确保你现有代码的兼容性。但这对你来说究竟意味着什么？让我们来详细分解一下。]]></description>
            <content:encoded><![CDATA[<p>SA<!-- -->:MP<!-- --> 已停滞多年，毫无更新，且需要大量变通方案才能维持运行。open.mp 改变了这一现状——它是一个完整的重写版本，修复了长期存在的问题，改进了脚本功能，并移除了旧的限制，同时确保你现有代码的兼容性。但这对你来说究竟意味着什么？让我们来详细分解一下。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>以下内容已过时，且大部分与 open.mp 的当前状态无关。本文发布于此仅作归档用。</p></div></div>
<p>长期以来，Kalcor 不再维护 SA<!-- -->:MP<!-- --> 已是显而易见的事实；这本身无可厚非，但作为唯一拥有官方源代码访问权限的人，这使他成为了新版本更新的瓶颈。YSF 和 fixes.inc 的创建都是为了填补这一空白——即在无法访问源代码的情况下修复服务器中的错误和不一致；前者是插件，后者是包含文件。尽管这些（以及其他）项目付出了巨大的努力，力求尽可能稳定、全面且易于使用，但它们自然也开始遇到自身的极限，需要新一代的修复方案。这就是 open.mp 诞生的原因。</p>
<p>open.mp 秉承同样的理念，并汲取了社区十多年来开发的无数改进，是对原始 SA<!-- -->:MP<!-- --> 服务器的从头重写，包含其直接前身的所有修复，以及许多难以管理或根本不可能实现的修复。诚然，这种方法并非没有争议——一些服务器已经开发了自己私有的方法来应对 SA<!-- -->:MP<!-- --> 的特性，独立于社区的努力，但这些技术并非每个脚本编写者都应为自己重新开发的，本文将帮助迁移现有代码。</p>
<p>我们希望解决主要的难点，但如果我们遗漏了任何问题，请随时通过 Discord 或 GitHub 联系我们，我们将很乐意修改本指南。</p>
<p>另一种选择是使用一个与 fixes.inc 对应的库——breaks.inc，来撤销这些修复：</p>
<p><a href="https://github.com/pawn-lang/sa-mp-fixes/blob/master/breaks.inc" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/sa-mp-fixes/blob/master/breaks.inc</a></p>
<p>因此，你可以自由安装它，通过钩子透明地恢复所有旧的行为。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="标签tags"><code>标签（Tags）</code><a href="https://omp.itsneufox.com/zh-CN/blog/porting#%E6%A0%87%E7%AD%BEtags" class="hash-link" aria-label="标签tags的直接链接" title="标签tags的直接链接" translate="no">​</a></h2>
<p>open.mp 的包含文件为函数添加了许多新标签，但仍试图在急需的升级和侵入性之间取得平衡。由于这些变更可能影响广泛，我们编写了一个工具来自动化处理其中大部分工作：</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hidemenuforplayer"><code>HideMenuForPlayer</code><a href="https://omp.itsneufox.com/zh-CN/blog/porting#hidemenuforplayer" class="hash-link" aria-label="hidemenuforplayer的直接链接" title="hidemenuforplayer的直接链接" translate="no">​</a></h2>
<p>此函数一直带有一个菜单 ID 参数，但在 SA<!-- -->:MP<!-- --> 中，此 ID 并未被使用。因此，无论给定什么值，玩家的当前菜单都会被关闭，即使他们看的并不是你指定的那个菜单。</p>
<p>旧代码可能如下所示：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">gShopMenu </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CreateMenu</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">HideMenuForPlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gShopMenu</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>无论玩家实际在看哪个菜单，上述代码总会关闭其当前菜单。现在，你需要记住他们正在看哪个菜单，或者直接获取它：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">gShopMenu </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CreateMenu</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">HideMenuForPlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">GetPlayerMenu</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setplayerattachedobject"><code>SetPlayerAttachedObject</code><a href="https://omp.itsneufox.com/zh-CN/blog/porting#setplayerattachedobject" class="hash-link" aria-label="setplayerattachedobject的直接链接" title="setplayerattachedobject的直接链接" translate="no">​</a></h2>
<p>在 SA<!-- -->:MP<!-- --> 中，附加的物件会在游戏模式变更后保留，但在 open.mp 中则不会。如果你希望玩家在模式重启后保留他们的物件，你需要在 <code>OnPlayerConnect</code> 中重新添加它们：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">enum</span><span class="token plain"> </span><span class="token class-name">E_ATTACHMENT_DATA</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_MODEL</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_BONE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_OFFSET_X</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_OFFSET_Y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_OFFSET_Z</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_ROT_X</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_ROT_Y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_ROT_Z</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_SCALE_X</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_SCALE_Y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_SCALE_Z</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_COLOUR_1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    E_ATTACHMENT_DATA_COLOUR_2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">public </span><span class="token function" style="color:#d73a49">OnPlayerConnect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">new i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> MAX_OBJECT_ATTACHMENT_SLOTS</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">++</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">SetPlayerAttachedObject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_MODEL</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_BONE</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_OFFSET_X</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_OFFSET_Y</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_OFFSET_Z</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_ROT_X</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_ROT_Y</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_ROT_Z</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_SCALE_X</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_SCALE_Y</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_SCALE_Z</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_COLOUR_1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            gAttachementData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">E_ATTACHMENT_DATA_COLOUR_2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="死亡金钱">死亡金钱<a href="https://omp.itsneufox.com/zh-CN/blog/porting#%E6%AD%BB%E4%BA%A1%E9%87%91%E9%92%B1" class="hash-link" aria-label="死亡金钱的直接链接" title="死亡金钱的直接链接" translate="no">​</a></h2>
<p>在圣安地列斯中，当玩家死亡时，会自动扣除其 $100 作为医疗费。此特性在 SA<!-- -->:MP<!-- --> 中保留，但在 open.mp 中被移除，以便脚本可以完全管理自己的金钱。已有一些脚本试图通过在玩家死亡后或重生时增加 $100 来修复此问题。如果你的脚本属于这种情况，直接删除这个额外的修复即可，尽管 open.mp 中的代码确实尝试考虑到了执行此操作的脚本。如果你的脚本依赖于此特性，只需在 <code>OnPlayerDeath</code> 中添加以下代码：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">GivePlayerMoney</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="游戏文本">游戏文本<a href="https://omp.itsneufox.com/zh-CN/blog/porting#%E6%B8%B8%E6%88%8F%E6%96%87%E6%9C%AC" class="hash-link" aria-label="游�戏文本的直接链接" title="游戏文本的直接链接" translate="no">​</a></h2>
<p>SA<!-- -->:MP<!-- --> 有六种不同的游戏文本样式，但其中几种基本无法使用。一种会不断淡入淡出，一种无论你设置多长时间都会在固定时间后消失，还有一种无论选择多长时间都永远不会消失。然而，事实证明，所有这些游戏文本样式都可以通过文本绘图准确地<sup><a href="https://omp.itsneufox.com/zh-CN/blog/porting#user-content-fn-1-fafbf6" id="user-content-fnref-1-fafbf6" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">1</a></sup>再现。因此 fixes.inc 以及随后的 open.mp 这样做了。游戏文本的外观与以前相同，优点是所有样式都可用，缺点是不再具有淡入淡出效果。</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">FadingGameTextForPlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> format</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> style</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">style </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 这些样式没有淡入淡出版本。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">GameTextForPlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> format</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> style</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 通过 Pawn.RakNet 发送原始消息</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="池大小">池大小<a href="https://omp.itsneufox.com/zh-CN/blog/porting#%E6%B1%A0%E5%A4%A7%E5%B0%8F" class="hash-link" aria-label="池大小的直接链接" title="池大小的直接链接" translate="no">​</a></h2>
<p><code>GetPlayerPoolSize</code>、<code>GetActorPoolSize</code> 和 <code>GetVehiclePoolSize</code> 在首次引入时有些多余；它们返回已连接的最高 ID，这与已连接玩家的数量无关，而且远在已有更好的循环方法出现之后。有点愚蠢本身并不是移除函数的理由，但不幸的是，当没有玩家连接时，它们也存在问题并返回错误数据。没有办法在既保持向后兼容性又确保未来正确性的情况下修复这些返回值（相信我，我们试过）。鉴于这些事实，我们选择直接移除这些函数。只需使用普通循环或 <code>foreach</code>：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">foreach</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">new i </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Player</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>引入此变更时，一些脚本确实会崩溃，但仅当使用以下循环形式时：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">new i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">GetPlayerPoolSize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">++</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>尽管当有玩家在线时，最高值是一个真实的玩家 ID，但这段代码本身就有问题——它漏掉了一个人。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="拼写">拼写<a href="https://omp.itsneufox.com/zh-CN/blog/porting#%E6%8B%BC%E5%86%99" class="hash-link" aria-label="拼写的直接链接" title="拼写的直接链接" translate="no">​</a></h2>
<p>SA<!-- -->:MP<!-- --> 在其代码拼写方面非常不一致——有些使用英式英语，有些使用美式英语：</p>
<ul>
<li class=""><code>Bumper</code> - 英式</li>
<li class=""><code>Hood</code> - 美式</li>
<li class=""><code>Armour</code> - 英式</li>
<li class=""><code>Stereo</code> - 美式</li>
</ul>
<p>我们已统一了这些拼写，并确定使用英式拼写。例如：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">TextDrawBoxColor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">textid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> boxColor</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>现在是：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">TextDrawBoxColour</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">textid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> boxColour</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>升级工具将自动处理其中大部分更改。</p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorTargetStickyNavbar_Vzrq sr-only" id="footnote-label">Footnotes<a href="https://omp.itsneufox.com/zh-CN/blog/porting#footnote-label" class="hash-link" aria-label="Footnotes的直接链接" title="Footnotes的直接链接" translate="no">​</a></h2>
<ol>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-1-fafbf6">
<p>有一个显著的例外——新的时钟游戏文本样式。出于未知的原因，时钟的颜色对不同的人显示不同，这导致在发现此差异之前，关于如何最好地复制此样式有很多来回的讨论。我们必须选择两者之一以保证一致性。 <a href="https://omp.itsneufox.com/zh-CN/blog/porting#user-content-fnref-1-fafbf6" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[候选版本 1]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/release-candidate-1</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/release-candidate-1</guid>
            <pubDate>Thu, 05 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[终于来了！🎉]]></description>
            <content:encoded><![CDATA[<p>终于来了！🎉</p>
<p>经过多年的开发、重写和各种挑战，我们非常激动地向大家介绍服务器的发布候选版本 1 (RC1)。这是我们迈向官方 1.0 版本的一个重要里程碑，带来了显著的更新、新特性和改进。</p>
<p>来了！它终于来了！经过四年时间，两次重写，争论与波折，以及无数的其他障碍；它终于来了！服务器的发布候选版本 1 (RC1)。这，希望代表着我们 1.0 发布的最终代码版本。如果此版本的运行一切顺利，我们将在几天后最终<strong>开放</strong>所谓的 <strong>open</strong>.mp。</p>
<p>在深入介绍本次发布的具体内容之前，我首先要诚挚地感谢团队的每一位成员，是他们的帮助让这款模组走到了今天。这并不容易，主要是因为每个人都真正地投入其中——我们都希望这款模组、社区、SA<!-- -->:MP<!-- -->、我们的服务器以及我们的玩家能获得最好的体验；如果不是这样，我们当初就不会开始这段旅程。不幸的是，对于什么才是“最好”的强大而不同的看法有时会导致摩擦。但现在，我们终于走到了这一步。</p>
<p>所以，对所有人，致以衷心的感谢：</p>
<ul>
<li class="">Amir</li>
<li class="">Cheaterman</li>
<li class="">Freaksken</li>
<li class="">Graber</li>
<li class="">Hual</li>
<li class="">Josh</li>
<li class="">JustMichael</li>
<li class="">kseny</li>
<li class="">Nexius</li>
<li class="">pkfin</li>
<li class="">Potassium</li>
<li class="">Southclaws</li>
<li class="">TommyB</li>
<li class="">Y_Less</li>
<li class="">Zeex</li>
<li class="">以及更多可能遗漏的人……</li>
</ul>
<p>好了，现在是你真正关心的部分……</p>
<p>既然我们已经离开了 Beta 测试阶段，并且（如果这周一切顺利的话）我们会按时发布。因此，除了你之前见过很多次的服务器本身，我们还有一些新的好东西给你：</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pawn">Pawn<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#pawn" class="hash-link" aria-label="Pawn的直接链接" title="Pawn的直接链接" translate="no">​</a></h2>
<p>下载包中包含了官方的包含文件，不再需要用 <code>omp.inc</code> 来修补旧的 SA<!-- -->:MP<!-- --> 包含文件了，现在我们正在以正确的方式做事！它还包含了一个新的编译器。是不是在想 3.10.11 什么时候发布？现在不用再等了（如果你自己构建过，可以把这个当作 3.10.12！）！有了这个组合，你可能会看到很多新的警告，但不用担心——我们也有一个工具来处理这个问题，可以自动升级大量代码，在适当的地方添加定义良好的符号名、<code>const</code> 等。</p>
<p>也许你已经注意到了，你已经用了好几个月了，但虚拟机（服务器内部的部分）也已经更新了！哦，还有那些你熟知和喜爱的字符串原生函数，比如 <code>SendClientMessage</code> 和 <code>AddMenuItem</code>？它们现在都支持格式化了。所有都支持！<sup><a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#user-content-fn-1-b9e74c" id="user-content-fnref-1-b9e74c" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">1</a></sup></p>
<p>以下是可用功能的完整列表：</p>
<ul>
<li class="">符号长度限制增加到 64 个字符，不再需要为了塞下名字而用 <code>OnPlyrDoTheTing</code> 这样的缩写了。这也导致了……</li>
<li class="">多个原生函数名称不再压缩——<code>Col</code> 是 <code>Colour</code> 还是 <code>Collision</code> 的缩写？现在你知道了！</li>
<li class="">标签。到处是标签。请参阅附带的文档。</li>
<li class="">官方包含文件终于具备 const 正确性。不再需要抱怨某些人可能没有它们了。</li>
<li class="">编译器版本已更新：<code>__nameof</code>、<code>__addressof</code>、修复，以及太多这里无法详述的内容。</li>
<li class=""><code>switch</code> 语句速度大幅提升。</li>
<li class="">针对以前无法检测到的问题增加了更多警告。编译器能找到的问题越多，你需要找的就越少。</li>
<li class="">一个<em>升级</em>工具，用于向用户代码添加标签和 <code>const</code>，并修复几个新警告。</li>
<li class="">命名更加一致。每个原生函数都经过仔细检查和比较，以确保命名的最大相似度和直观性。</li>
<li class="">到处都添加了 <code>{Float, _}:...</code>。这意味着什么？意味着基本不需要 <code>format()</code> 了<sup><a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#user-content-fn-2-b9e74c" id="user-content-fnref-2-b9e74c" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">2</a></sup>——想象一下原生的 y_va。</li>
<li class="">在使用新编译器和虚拟机时，<code>-O2</code> 这个最高的 pawn 优化级别可以工作。一些包含文件可能需要更新，但有些已经更新了。为了帮助解决这个问题……</li>
<li class="">添加了 <code>__optimisation</code> 宏，以便代码在通过 -O2 编译时可以配置自身。</li>
</ul>
<p>更新后的包含文件的文档：</p>
<p><a href="https://github.com/openmultiplayer/omp-stdlib" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/omp-stdlib</a></p>
<p>新编译器的文档：</p>
<p><a href="https://github.com/openmultiplayer/compiler" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/compiler</a></p>
<p><a href="https://github.com/pawn-lang/compiler" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/compiler</a></p>
<p>qawno 的文档：</p>
<p><a href="https://github.com/openmultiplayer/qawno" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/qawno</a></p>
<p>升级工具的文档：</p>
<p><a href="https://github.com/openmultiplayer/upgrade" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/upgrade</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sdk">SDK<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#sdk" class="hash-link" aria-label="SDK的直接链接" title="SDK的直接链接" translate="no">​</a></h2>
<p>Pawn 是长期以来（并且仍然是）为你的服务器编写模式的官方方式。它不会消失，但对于那些想要更多控制权的朋友，我们终于发布了完整的 SDK（<em>S</em>oftware <em>D</em>evelopment <em>K</em>it，软件开发工具包）。这是一个通往服务器的 C++ 接口，与构成核心代码的所有组件使用的接口相同。它们能做的任何事情，你也能做（相比之下，插件仅设计为向 pawn 提供函数，而不是编写模式）。</p>
<p>我们正在编写一些文档，但不幸的是这需要时间。但与此同时，我们为那些想直接上手的朋友提供了几个示例组件。这些都是你可以构建的模板，可以从几乎零开始，到一个具备最常见功能的完全可运行的组件：</p>
<p><a href="https://github.com/openmultiplayer/empty-template" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/empty-template</a></p>
<p><a href="https://github.com/openmultiplayer/basic-template" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/basic-template</a></p>
<p><a href="https://github.com/openmultiplayer/pawn-template" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/pawn-template</a></p>
<p><a href="https://github.com/openmultiplayer/full-template" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/full-template</a></p>
<p>一些术语让你入门，帮助你理解正在阅读的内容：</p>
<ul>
<li class=""><em>组件</em> - 服务器的一个逻辑独立部分，比如物体或拾取物。你不需要的部分可以不用加载。</li>
<li class=""><em>扩展</em> - 扩展另一段代码的代码。你可以编写组件扩展，但最常见的是玩家扩展，它定义了一些数据结构，用于在玩家所有正常数据（如生命值和武器）之外，与玩家关联。</li>
<li class=""><em>UID</em> - 唯一标识符，一个代表你且仅代表你组件的数字。这总是必需的，可以在这里获取：<a href="https://open.mp/uid" target="_blank" rel="noopener noreferrer" class="">https://open.mp/uid</a></li>
<li class=""><em>实体</em> - 一个东西，通常是玩家可以与之交互的东西，并且你可能有很多这样的东西。物体是实体，但其他玩家也是实体，甚至处理器中的命令也可以称为实体。</li>
<li class=""><em>池</em> - 容纳实体的东西。当你有大量实体时，你需要能够通过名称或 ID 以某种方式访问它们，这就是池的作用。</li>
<li class=""><em>接口</em> - 组件使用一个抽象基类作为接口。这声明了组件具有哪些方法，但不包含这些方法的代码。接口被传递，以便组件之间可以相互通信，但实现是私有的。</li>
<li class=""><em>SDK</em> - 核心服务器定义的所有接口的集合。</li>
<li class=""><em>ABI</em> - 应用程序二进制接口，是编译后的代码与其他编译代码通信的方式。SDK 导出的接口是 <em>ABI 稳定的</em>，这意味着使用在不同时间编译的两个组件仍然可以协同工作。</li>
<li class=""><em>pawn-natives</em> - 所有原生函数声明构建于其上的库。围绕此库使用一个名为 <em>SCRIPT_API</em> 的包装器：<a href="https://github.com/openmultiplayer/pawn-natives" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/pawn-natives</a></li>
<li class=""><em>事件</em> - 外部发生的某些事情。比如玩家连接和输入命令就是事件。任何组件都可以定义事件，并告诉其他组件这些事件何时发生。</li>
<li class=""><em>处理器</em> - 想知道事件何时发生的组件。</li>
</ul>
<p>如果你有任何问题，最好的地方可能是这个全新的（复兴的）论坛：
<a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp/</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="新特性的直接链接" title="新特性的直接链接" translate="no">​</a></h2>
<p>除了为 pawn 宣布的所有新特性外，服务器中还有几个新的（以及新宣布的）特性：</p>
<ul>
<li class="">每个玩家的帮派区域，类似于 YSF 中那样。</li>
<li class="">每个玩家的拾取物，也类似于 YSF 中那样。</li>
<li class=""><code>AttachPlayerObjectToPlayer</code>。</li>
<li class="">更好的 PawnPlus 支持。</li>
<li class=""><code>:memory:</code> 以及其他特殊名称在 SQLite 中的支持。</li>
<li class="">SQLite 打开标志。</li>
<li class=""><code>exclude</code> 配置选项，用于不加载特定组件。</li>
<li class="">显示配置解析错误，而不是默默地失败。</li>
<li class="">SDK 主版本检查，以防我们将来对服务器进行重大更改（希望我们不会）。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="修复">修复<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#%E4%BF%AE%E5%A4%8D" class="hash-link" aria-label="修复的直接链接" title="修复的直接链接" translate="no">​</a></h2>
<p>在 beta 11 中引入了一些新 bug，以及之前遗留的一些小问题。修复的问题包括：</p>
<ul>
<li class=""><code>funcidx</code> 已注册的警告。</li>
<li class="">GDK 插件（例如 streamer 等）缺少原生函数。</li>
<li class="">GMX 时随机崩溃。</li>
<li class="">有时不调用 GDK 回调。</li>
<li class="">SQLite 组件在请求时没有记录日志。</li>
<li class="">某些设置在 GMX 时未重置。</li>
<li class="">当一次性创建大量 NPC 时，NPC 连接出现问题。</li>
<li class="">Linux 遗留插件名称中仍然需要 <code>.so</code> 后缀。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="链接">链接<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#%E9%93%BE%E6%8E%A5" class="hash-link" aria-label="链接的直接链接" title="链接的直接链接" translate="no">​</a></h2>
<p>首先，当然是新服务器版本：</p>
<p><a href="https://github.com/openmultiplayer/open.mp/releases" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/open.mp/releases</a></p>
<p>其次，论坛重新上线了。有任何问题请前往：
<a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp</a>
或者
<a href="https://vk.com/open_mp" target="_blank" rel="noopener noreferrer" class="">https://vk.com/open_mp</a>如果你喜欢。</p>
<p>接下来，尽管我们多次拒绝，但到目前为止我们明确抵制任何金钱资助；因为在我们通过发布版本来证明自己之前，我们认为这不合适。随着这篇文章的发布，这个时刻现在已经到来，所以如果有人想帮助我们（所有捐款将用于基础设施和未来的客户端开发工作），我们将不胜感激：
<a href="https://opencollective.com/openmultiplayer" target="_blank" rel="noopener noreferrer" class="">https://opencollective.com/openmultiplayer</a></p>
<p><a href="https://www.patreon.com/open_mp" target="_blank" rel="noopener noreferrer" class="">https://www.patreon.com/open_mp</a></p>
<p>当然，一切仍在积极开发中，所以请务必定期查看以上所有链接，看看我们又有了什么新东西。</p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorTargetStickyNavbar_Vzrq sr-only" id="footnote-label">Footnotes<a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#footnote-label" class="hash-link" aria-label="Footnotes的直接链接" title="Footnotes的直接链接" translate="no">​</a></h2>
<ol>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-1-b9e74c">
<p>几乎是所有的。 <a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#user-content-fnref-1-b9e74c" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-2-b9e74c">
<p>几乎不需要 <code>format()</code> 了。 <a href="https://omp.itsneufox.com/zh-CN/blog/release-candidate-1#user-content-fnref-2-b9e74c" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[支持 SA-MP 0.3.DL 及其他新特性与错误修复 - 服务器测试版发布 9]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/server-beta-9</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/server-beta-9</guid>
            <pubDate>Thu, 08 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[我们刚刚发布了 open.mp 服务器测试版 9，带来了重大改进、修复以及万众期待的 SA:MP 0.3.DL 支持！此次更新包含了新特性、更好的插件兼容性以及增强的服务器配置选项。]]></description>
            <content:encoded><![CDATA[<p>我们刚刚发布了 open.mp 服务器测试版 9，带来了重大改进、修复以及万众期待的 SA<!-- -->:MP<!-- --> 0.3.DL 支持！此次更新包含了新特性、更好的插件兼容性以及增强的服务器配置选项。</p>
<p>发布于我们的 Discord 服务器公告频道，作者 kseny (<a href="https://discord.gg/samp" target="_blank" rel="noopener noreferrer" class="">discord.gg/samp</a>)</p>
<p>大家好，</p>
<p>我们刚刚发布了 open.mp 服务器测试版 9，修复了数个已报告的问题并新增了多项功能。最值得注意的变化是——<strong>支持 SA<!-- -->:MP<!-- --> 0.3.DL</strong>。你现在可以使用同一个二进制文件来运行兼容 0.3.7 和 0.3.DL 的服务器了。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="其他变更">其他变更<a href="https://omp.itsneufox.com/zh-CN/blog/server-beta-9#%E5%85%B6%E4%BB%96%E5%8F%98%E6%9B%B4" class="hash-link" aria-label="其他变更的直接链接" title="其他变更的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><strong>动态 Tick 率</strong>。指定一个目标 tickrate，而非固定的休眠时间。<!-- -->
<ul>
<li class="">使用 <code>tickrate</code> 控制台命令来设置速率。</li>
<li class=""><code>sleep</code> 现在可以是浮点数，以适应精确的 tick 率。</li>
</ul>
</li>
<li class=""><strong>更强的插件兼容性</strong> - fsutil, Discord connector（仅限非静态构建版本）。</li>
<li class="">修复了 <code>SetSpawnInfo</code> 的返回值。</li>
<li class="">修复了 GMX 后天气和时间不重置的问题。</li>
<li class="">修复了各种 GMX 相关错误。</li>
<li class="">修复了各种控制台命令。</li>
<li class="">修复了 <code>GetPlayerClass</code>。</li>
<li class="">修复了 <code>GetVehicleLastDriver</code>。</li>
<li class="">新增 <code>GetVehicles</code> 原生函数。</li>
<li class="">新增 <code>GetPlayers</code> 原生函数。</li>
<li class="">新增 <code>GetActors</code> 原生函数。</li>
<li class="">所有延迟补偿模式现在都可以通过配置启用。</li>
<li class="">修复了拖车同步。</li>
<li class="">修复了 <code>GetVehicleLastDriver</code>。</li>
<li class="">修复了 <code>GetPlayerRotationQuat</code>。</li>
<li class="">修复了车辆组件的崩溃问题。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sa-dl">SA<!-- -->:MP<!-- --> DL<a href="https://omp.itsneufox.com/zh-CN/blog/server-beta-9#sa-dl" class="hash-link" aria-label="sa-dl的直接链接" title="sa-dl的直接链接" translate="no">​</a></h2>
<p>这显然是最大的新闻，并且附带了一系列全新的设置：</p>
<ul>
<li class="">实现了所有 DL 原生函数和回调（<code>AddSimpleModel</code>、<code>AddSimpleModelTimed</code>、<code>GetPlayerCustomSkin</code>、<code>OnPlayerFinishedDownloading</code>、<code>OnPlayerRequestDownload</code>）：<!-- -->
<ul>
<li class=""><code>RedirectDownload</code> 原生函数和 <code>OnPlayerRequestDownload</code> 回调现在已被弃用，建议使用 CDN 配置选项替代。</li>
</ul>
</li>
<li class="">新增 <code>artwork.enable</code>（旧版：<code>useartwork</code>）配置选项。</li>
<li class="">新增 <code>artwork.models_path</code>（旧版：<code>artpath</code>）配置选项。<!-- -->
<ul>
<li class="">服务器可以像 SA<!-- -->:MP<!-- --> 一样从 <code>artconfig.txt</code> 文件加载自定义模型。</li>
</ul>
</li>
<li class="">保留了 0.3.7 兼容性，可通过 <code>network.allow_037_clients</code> 配置选项进行配置（默认为 true）。</li>
<li class="">open.mp 服务器现在内置了一个用于提供自定义模型的网络服务器<!-- -->
<ul>
<li class="">该网络服务器使用 open.mp 服务器的绑定地址和端口。如果计划使用它，请在防火墙中允许该端口的 TCP 连接。</li>
<li class="">如果你的公网 IP 地址与绑定地址不同（例如，在路由器后面），你需要在 <code>network.public_addr</code> 配置选项中设置你的公网 IP。</li>
</ul>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="注意事项">注意事项<a href="https://omp.itsneufox.com/zh-CN/blog/server-beta-9#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9" class="hash-link" aria-label="注意事项的直接链接" title="注意事项的直接链接" translate="no">​</a></h2>
<ul>
<li class="">由于一些更改，旧的 config.json 文件可能无法正常工作。请使用 <code>./omp-server --default-config</code> 来生成一个新的配置文件。</li>
<li class="">使用 server.cfg 的用户不受影响。</li>
<li class="">在仅允许 0.3.7 连接时，最多只能创建 1000 个物体。</li>
<li class="">open.mp 服务器现在提供两种类型的 Linux 构建：标准版和静态版。我们鼓励尽可能使用标准版，这将最大限度地减少与各种插件的兼容性问题；但是，它需要系统上安装有 openssl 1.1。如果你的系统无法安装现代版本的 openssl（通常是非常旧的系统），可以使用静态版，但一些插件或组件可能加载失败并导致服务器崩溃。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="官方包含文件">官方包含文件<a href="https://omp.itsneufox.com/zh-CN/blog/server-beta-9#%E5%AE%98%E6%96%B9%E5%8C%85%E5%90%AB%E6%96%87%E4%BB%B6" class="hash-link" aria-label="官方包含文件的直接链接" title="官方包含文件的直接链接" translate="no">​</a></h2>
<p>准备一个完整的版本不仅仅是一个可工作的服务器，还需要所有其他周边——库、工具、文档等。在 Pawn 方面，open.mp 是一个显著的升级，通过修复和新特性已经带来了许多生活质量提升，未来还会有更多。本次推动的一个重要部分是<strong>通过更多的编译器诊断功能来提前发现代码问题</strong>，主要是通过更多的标签和常量正确性来实现。虽然官方版本尚未发布，但你仍然可以通过使用以下包含文件和工具测试你的代码来提供帮助：</p>
<p><a href="https://github.com/pawn-lang/samp-stdlib/tree/consistency-overhaul" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/samp-stdlib/tree/consistency-overhaul</a><br>
<a href="https://github.com/pawn-lang/pawn-stdlib/tree/backported-natives" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/pawn-stdlib/tree/backported-natives</a><br>
<a href="https://github.com/openmultiplayer/upgrade" target="_blank" rel="noopener noreferrer" class="">https://github.com/openmultiplayer/upgrade</a><br>
<a href="https://github.com/pawn-lang/compiler" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/compiler</a></p>
<p>这些项目最初是为了改进默认的 SA<!-- -->:MP<!-- --> 包含文件而开发的，但从未完全发布（即，尽管 PR 被接受，但从未合并到主分支）。open.mp 的包含文件建立在这些项目奠定的基础上，因此可以将它们视为通往完整的 open.mp 标签和常量安全的垫脚石；同时也是关于其发展方向的重要反馈。请参阅上面的链接，了解关于升级的更多信息和文档。</p>
<p>和以往一样，如果你不想升级，旧代码和包含文件仍然可以工作（至少在第一个版本中）。</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022 更新 - 跨平台游戏与 Beta 测试 (新年快乐 🎉)]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/update-2022</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/update-2022</guid>
            <pubDate>Sat, 01 Jan 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[经过多年的开发、实验和一次彻底的重写，open.mp 正在迎来一个重要的里程碑！我们即将启动首个半公开 Beta 测试计划，并且正在着手开发一个巨大的项目——实现不同版本《侠盗猎车手：圣安地列斯》之间的跨平台联机支持。]]></description>
            <content:encoded><![CDATA[<p>经过多年的开发、实验和一次彻底的重写，open.mp 正在迎来一个重要的里程碑！我们即将启动首个半公开 Beta 测试计划，并且正在着手开发一个巨大的项目——实现不同版本《侠盗猎车手：圣安地列斯》之间的跨平台联机支持。</p>
<p>大家好！</p>
<p>自 open.mp 问世至今已过去三年，历经多次实验和重写，这些年我们尝试了各种不同的方法，以寻找最适合我们和社区的发展道路，如今，我们终于来到这里。不过，首先讲一点背景故事或许会更好：</p>
<p>我们于 2019 年初启动了 open.mp 项目，并在问世后获得了大量关注。然而，我们未能按部就班、从容地推进工作，而是不得不仓促上阵，这给我们的项目管理、团队协作和代码库带来了一些问题。我们距离最初的目标还很遥远。我们的实现虽然强大，但同时也变得复杂且难以持续维护。这使我们难以遵循既定的路线图，因此，我们必须做出一个决定：启动一次重写。</p>
<p>重写在 2021 年 6 月，经过数月的沉寂，open.mp 团队决定启动一次重写，目标是构建一个 1:1 完全替代 SA<!-- -->:MP<!-- --> 的服务器（确保所有内容向后兼容），并在修复问题的同时添加一些新特性。我们将专注于更重要的事情，额外的特性可以留待日后添加。</p>
<p>现在，我们终于要启动首个半公开的 Beta 测试计划了。我们诚邀拥有 Pawn 语言技能的服务器开发者帮助我们进行全面测试，包括检查所有原生函数及其预期响应，以及使用他们现有的 SA<!-- -->:MP<!-- --> 脚本和玩家群进行压力测试。公告发布后，我们会附上测试者申请表的链接。如果你认为自己能够在这个过程中帮助我们，欢迎随时报名。</p>
<p>最后但同样重要的是，我们激动地宣布，我们的团队已开始着手为《侠盗猎车手：圣安地列斯》重制版开发客户端！open.mp 的重制版客户端将与 open.mp 服务器兼容！这意味着，你只需架设一个服务器，就可以让玩家自行决定使用哪个版本的游戏加入服务器！想象一下，在一个 open.mp 服务器上，同时有使用原版、安卓版和重制版的圣安地列斯玩家，同处一服，一起游戏。这是我们为使所有版本相互兼容、为社区带来跨平台游戏体验所做的最后一次，也是最艰难的一次尝试。</p>
<p>这样一来，作为服务器所有者，你无需担心要迁移到新平台、重新开始并导致社区分裂。因为我们将让每个人都能在同一个服务器上使用他们的 SA<!-- -->:MP<!-- --> 脚本，而玩家可以自行决定使用哪个游戏来连接服务器！</p>
<p>感谢各位在这漫长而艰辛的旅程中与我们同行，我们为拥有这样一个庞大的社区而感到自豪！新年快乐 🎉，2022 年对我们来说将是美好的一年，也标志着我们钟爱的多人联机模组 SA<!-- -->:MP<!-- --> 将迎来变革。来自我们所有人的爱 ❤️</p>
<p>以下是我们首次尝试测试 open.mp 《侠盗猎车手：圣安地列斯》重制版客户端首个版本的视频，其中包含了 SA<!-- -->:MP<!-- --> PC 版和 SA<!-- -->:MP<!-- --> 安卓版客户端，三者同处于一个 open.mp 服务器中：<a href="https://www.youtube.com/watch?v=-PWXXvHe35M" target="_blank" rel="noopener noreferrer" class="">https://www.youtube.com/watch?v=-PWXXvHe35M</a></p>
<p>我们的 Beta 测试者申请表可以在这里找到：<a href="https://airtable.com/shrjqca2tpgYa9sQL" target="_blank" rel="noopener noreferrer" class="">https://airtable.com/shrjqca2tpgYa9sQL</a></p>
<p>温馨提示：我们目前正在为我们的 open.mp 服务器项目寻找 Beta 测试者，这与客户端无关。此次招募针对脚本编写者/开发者，目前尚不需要普通玩家参与。请不要就客户端事宜向我们发送消息，如果你无法帮助我们测试 open.mp 的服务器端，也请不要填写申请表。你需要对 Pawn 语言有较好的掌握，并熟悉 samp 脚本编写。</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[如何加入我们的团队？]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team</guid>
            <pubDate>Sun, 29 Aug 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[想成为 open.mp 团队的一员吗？我们经常收到这个问题，以下是你参与贡献和加入我们的方式！]]></description>
            <content:encoded><![CDATA[<p>想成为 open.mp 团队的一员吗？我们经常收到这个问题，以下是你参与贡献和加入我们的方式！</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="如何加入我们的团队">如何加入我们的团队？<a href="https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team#%E5%A6%82%E4%BD%95%E5%8A%A0%E5%85%A5%E6%88%91%E4%BB%AC%E7%9A%84%E5%9B%A2%E9%98%9F" class="hash-link" aria-label="如何加入我们的团队？的直接链接" title="如何加入我们的团队？的直接链接" translate="no">​</a></h2>
<p>我们收到了太多关于这个问题的询问，所以觉得应该专门写一篇帖子来说明！</p>
<p>首先，非常感谢你有兴趣为项目贡献力量！</p>
<p>正如你所知，我们是一群资深的 SA-MP 玩家，为了守护圣安地列斯多人联机世界而汇聚于此。我们坚信这个项目是<strong>为玩家服务、由玩家创造</strong>的，这也是为什么它最终会走向开源。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="开发">开发<a href="https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team#%E5%BC%80%E5%8F%91" class="hash-link" aria-label="开发的直接链接" title="开发的直接链接" translate="no">​</a></h2>
<p>我们目前正在为 Beta 版的发布做最后的收尾工作，一旦它正式上线，我们将非常感激并欢迎来自社区的贡献！我们需要大家帮助测试各项功能、边界情况，当然还有寻找漏洞以及其他需要解决的问题。</p>
<p>Beta 测试将是开发旅程中极其重要的一环，我们衷心希望每个人都能参与其中，所以请密切关注 Beta 测试的公告，我们保证它<strong>真的、真的快要来了</strong>！</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="地区协调员">地区协调员<a href="https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team#%E5%9C%B0%E5%8C%BA%E5%8D%8F%E8%B0%83%E5%91%98" class="hash-link" aria-label="地区协调员的直接链接" title="地区协调员的直接链接" translate="no">​</a></h2>
<p>你是否能<strong>流利</strong>地使用<strong>英语和另一门语言</strong>？我们非常需要你帮助翻译我们的维基页面、博客文章和社交媒体内容，并协助管理我们 Discord 和论坛中相应语言版块。</p>
<p>目前，在我们进行一些调整期间，这些职位的申请暂时关闭，但很快就会重新开放！</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="其他帮助方式">其他帮助方式<a href="https://omp.itsneufox.com/zh-CN/blog/how-to-join-the-team#%E5%85%B6%E4%BB%96%E5%B8%AE%E5%8A%A9%E6%96%B9%E5%BC%8F" class="hash-link" aria-label="其他帮助方式的直接�链接" title="其他帮助方式的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><strong>分享</strong> 我们的社交媒体帖子</li>
<li class=""><strong>邀请</strong> 其他 SA 玩家加入我们的 Discord (discord.gg/samp)</li>
<li class="">在 Discord 上积极<strong>参与</strong>我们的社区活动</li>
<li class="">在 Discord 上<strong>帮助</strong>其他玩家（脚本编写、技术支持，无论什么都可以！）</li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[10,000 名成员！]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/10k-members</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/10k-members</guid>
            <pubDate>Fri, 16 Jul 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[我们刚刚达成了一个不可思议的里程碑——我们 Discord 服务器的用户数突破了 10,000 人！🎉 已经有一段时间没更新了，所以在这里快速同步一下近况以及 open.mp 的下一步计划。]]></description>
            <content:encoded><![CDATA[<p>我们刚刚达成了一个不可思议的里程碑——我们 Discord 服务器的用户数突破了 10,000 人！🎉 已经有一段时间没更新了，所以在这里快速同步一下近况以及 open.mp 的下一步计划。</p>
<p>大家好！</p>
<p>我们最近达成了一个令人惊叹的里程碑：<strong>我们 Discord 服务器的用户数正式突破了 10,000 人！</strong> 🥳🔟🥳</p>
<p>我们觉得应该借此机会给大家一个小更新，因为我们知道已经有一段时间了，大家都在关心项目进展如何！</p>
<p>由于开发团队的所有成员都有自己的全职工作和其他事务，而且新冠疫情的情况也确实对大家造成了不小的影响。这意味着，我们最近这段时间确实没有太多时间能投入到 open.mp 上。</p>
<p>但是，情况最近已经开始好转，我们依然活跃，项目实际上正以比以往更快的速度推进，我们在过去几周取得的进展比之前很长一段时间都要多！</p>
<p>我们为这项工作以及我们所拥有的这支精益求精的卓越团队感到无比自豪。</p>
<p>在未来几个月，我们会提供更详细的信息，现在我们只想确保每个人都知道：<strong>我们没有放弃 open.mp</strong>，热情依然在，并且我们正在尽最大努力。所以请继续与我们同行，我们很快就会有新消息、截图和视频发布！</p>
<p>同时，欢迎来我们的 Discord 服务器和我们一起玩！感谢你们每一位，感谢这 10,000+ 位朋友 🥰</p>
<p>我们的 Discord 服务器是所有《圣安地列斯》多人联机模组和社区玩家与朋友的温馨聚集地！我们推广的活动包括：</p>
<p>✅ <strong>社区</strong>：与老朋友们一起闲逛，认识新朋友，找到老朋友和资深玩家，在专属语言频道里找到来自你国家/地区的人，结识来自 SA-MP / MTA / 其他多人联机模组的伙伴</p>
<p>✅ <strong>脚本编写</strong>：学习脚本编写，为你的脚本寻求帮助，帮助他人</p>
<p>✅ <strong>服务器宣传</strong>：在专属频道里展示你的 SA-MP 服务器</p>
<p>✅ <strong>编程与技术</strong>：讨论并获取其他编程语言和软件开发的帮助，获得技术支持，结识志同道合的人一起合作</p>
<p>✅ <strong>游戏</strong>：找人一起玩游戏（不只是 SA！），讨论游戏新闻和更新</p>
<p>✅ <strong>展示</strong>：你是 YouTuber 吗？主播？艺术家？会制作很酷的音乐？或者你是个厨师？也许你喜欢钓鱼？或者组装汽车？无论你为<strong>什么</strong>感到自豪，都来展示一下吧！</p>
<p>✅ <strong>open.mp</strong>：了解 open.mp 最新的开发进展和 GitHub 动态，与团队一起交流，当我们的 Discord VIP 专属开发直播恢复时，别忘了观看！</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SA-MP 安卓版（移动端）]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/samp-mobile</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/samp-mobile</guid>
            <pubDate>Sat, 30 Jan 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[我们收到了很多关于安卓版 SA-MP 的询问，因此想分享我们对于合法联机替代方案的看法和计划。]]></description>
            <content:encoded><![CDATA[<p>我们收到了很多关于安卓版 SA-MP 的询问，因此想分享我们对于合法联机替代方案的看法和计划。</p>
<p><strong>open.mp 团队对安卓版 SA-MP 的看法</strong></p>
<p>大家好，</p>
<p>我们想就我们对安卓版 SA-MP 的看法写一篇简短的博客文章，因为我们在 YouTube 视频和 Discord 上收到了大量相关的评论。</p>
<p>正如我们在 YouTube 视频中所述，<strong>我们不支持当前版本的安卓版 SA-MP</strong>。这个应用程序是使用从 SA-MP 团队<strong>窃取</strong>的源代码创建的，这使得该应用程序是非法的。</p>
<p>我们<strong>绝不容忍</strong>盗窃他人代码的行为，也<strong>绝不允许</strong>使用盗用来的代码。我们同样不与任何非法活动产生关联。</p>
<p>我们认识到移动端 GTA SA 联机拥有庞大的社区，我们<strong>欢迎这个社区加入 open.mp</strong>。</p>
<p>我们目前正在讨论如何为《圣安地列斯》移动端创建我们自己的联机模组，从而以<strong>合法且公平</strong>的方式实现它！:)</p>
<p>这意味着未来<strong>非常有可能</strong>会出现官方的 <strong>"open.mp 移动端"</strong>，所以在我们研究如何实现的同时，请继续支持我们！</p>
<p>我们邀请移动端社区加入我们拥有超过 7000 名成员的官方 Discord，我们已经为你们创建了 <code>#samp-android</code> 频道，并期待听到你们的想法和意见！</p>
<p>我们在那里见！</p>
<p><a href="https://discord.gg/samp" target="_blank" rel="noopener noreferrer" class="">https://discord.gg/samp</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Live Podcast]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/interview</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/interview</guid>
            <pubDate>Mon, 23 Nov 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[We recently hosted a live Q&A podcast with the open.mp dev team, covering everything from project updates and scripting improvements to future plans and community involvement. If you missed it, you can watch the full recording here!]]></description>
            <content:encoded><![CDATA[<p>We recently hosted a live Q&amp;A podcast with the open.mp dev team, covering everything from project updates and scripting improvements to future plans and community involvement. If you missed it, you can watch the full recording here!</p>
<p>On the 24th of October we had a dev Q&amp;A podcast, which is recorded for you below:</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="video">Video<a href="https://omp.itsneufox.com/zh-CN/blog/interview#video" class="hash-link" aria-label="Video的直接链接" title="Video的直接链接" translate="no">​</a></h2>
<p><a href="https://www.youtube.com/watch?v=bTYWWsXkcDo" target="_blank" rel="noopener noreferrer" class="">https://www.youtube.com/watch?v=bTYWWsXkcDo</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="transcript">Transcript<a href="https://omp.itsneufox.com/zh-CN/blog/interview#transcript" class="hash-link" aria-label="Transcript的直接链接" title="Transcript的直接链接" translate="no">​</a></h2>
<p><strong>Potassium:</strong><br>
<!-- -->hello everyone welcome to our very first live stream for open multiplayer<br>
<!-- -->um can i get a mic check can someone tell me if this is working please? jamie?</p>
<p><strong>everyone:</strong><br>
<!-- -->it's working<br>
<!-- -->it's working<br>
<!-- -->okay<br>
<!-- -->yeah<br>
<!-- -->yeah i heard it coming through on the other side<br>
<!-- -->yeah it's quite a delay<br>
<!-- -->yeah that's okay</p>
<p><strong>Potassium:</strong><br>
<!-- -->alright um hello uh what's up<br>
<!-- -->we're finally here and doing this i guess, um</p>
<p><strong>Southclaws:</strong><br>
<!-- -->many days of planning</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes<br>
<!-- -->maybe we should start by introducing ourselves, so... <strong>Southclaws</strong>?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that's me</p>
<p><strong>Potassium:</strong><br>
<!-- -->tell everyone a little bit about yourself and what you do here</p>
<p><strong>Southclaws:</strong><br>
<!-- -->uh yeah i think i've been around SAMP for like um since 2008 or 2007 i can't remember... a long time ago... um i just kind of do the website stuff at the moment, i manage the wiki and do a tiny bit of coding, but not too much, these guys are far better at that than i am. but yeah i do the wiki stuff mainly, and the website so that's kind of my area</p>
<p><strong>Potassium:</strong><br>
<!-- -->and <strong>Y_Less</strong>?</p>
<p><em>stream alert CJ's "here we go again"</em></p>
<p><strong>Y_Less:</strong><br>
<!-- -->hi i'm Y_Less:<br>
<!-- -->i've been in SAMP longer than you have<br>
<!-- -->i made my way onto the beta team before it was even released so there we go, it's been a while. i'm a former dev, i'm not entirely sure if i need to introduce myself but there we go</p>
<p><strong>Southclaws:</strong><br>
<!-- -->no probably not</p>
<p><strong>Potassium:</strong><br>
<!-- -->probably not</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i'm sure everybody knows you</p>
<p><strong>Potassium:</strong><br>
<!-- -->just in case</p>
<p><strong>Y_Less:</strong><br>
<!-- -->scripters know me, but not necessarily players</p>
<p><strong>Potassium:</strong><br>
<!-- -->no i'm pretty sure everyone does</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i'm also the only form of dev currently not purged from the client "about" page</p>
<p><strong>Potassium:</strong><br>
<!-- -->uhhh... nice... i guess?</p>
<p><strong>BigETI:</strong><br>
<!-- -->that's an achievement</p>
<p><strong>Potassium:</strong><br>
<!-- -->that's an achievement, yeah<br>
<!-- -->ok, josh, your turn</p>
<p><strong>j0sh.../alasnkz:</strong><br>
<!-- -->well i'm josh and i'm one of the main developers of open.mp<br>
<!-- -->i've been in samp for at least seven years now<br>
<!-- -->started programming six years because of samp<br>
<!-- -->and if you've been on the discord you know who i am, i'm always there, and always able to talk to you if you need any help for anything</p>
<p><strong>Potassium:</strong><br>
<!-- -->oh that was very wholesome<br>
<!-- -->who are you and what have you done with josh?<br>
<!-- -->ok, Amir?</p>
<p><strong>iAmir:</strong><br>
<!-- -->well i'm Amir and i've been around since 2010 i guess, that's the time i started playing samp actually. i'm just part of open.mp development team and i just kind of help the coding and stuff like that</p>
<p><strong>Potassium:</strong><br>
<!-- -->nice! and bigETI?</p>
<p><strong>BigETI:</strong><br>
<!-- -->yeah i'm bigeti, i'm 27 years old, i started playing samp around 2009, and contributed to projects, had my own servers, etc, and also i'm a contributor to<br>
<!-- -->open.mp now</p>
<p><strong>Potassium:</strong><br>
<!-- -->awesome, and michael?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i'm JustMichael:, i've been around since 2007, owned a few communities, fought my way up, these days though i pretty much just follow Southclaws: and manage all his projects that he's abandoned! and other than that i just work in free time on open.mp</p>
<p><strong>Southclaws:</strong><br>
<!-- -->he's the surrogate father to everything i've created</p>
<p><em>everyone laughs</em></p>
<p><strong>Potassium:</strong><br>
<!-- -->awesome!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->who are you Potassium?</p>
<p><strong>Potassium:</strong><br>
<!-- -->that is a good question! so i'm Potassium, obviously, i've been in the samp community since about 2008/2009 maybe... so like 10 years... or more i guess... maths!<br>
<!-- -->i'm not a scripter, i keep telling everyone that i will be maybe one day, i probably won't be, but anyway! i don't really have a backstory i'm just some random from the samp forum and i just, i don't know, i just love this community and want to be a part of keeping it alive so i kind of just invited myself to this team... so yay!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->that's fine, you do a fairly important job</p>
<p><strong>BigETI:</strong><br>
<!-- -->you're definitely welcome!</p>
<p><strong>Potassium:</strong><br>
<!-- -->i can't do any technical things, they're completely over my head, so we just named my role "public relations" and i just post stupid memes every now and again... but that's okay! someone needs to!</p>
<p><strong>Potassium:</strong><br>
<!-- -->so is there any point in quickly explaining what openmp is actually about or? i guess, yeah i guess we should, just in case anyone's listening and isn't quite sure. so basically we're all old school players of san andreas as you just heard, and we're all part of a community<br>
<!-- -->called san andreas multiplayer, it's a multi-player modification for san andreas and it's a little bit outdated now i guess you could say, so we're just kind of trying to breathe some more life back into it because we're not ready to let our little community die yet. is that is that a fair summary?</p>
<p><strong>everyone:</strong><br>
<!-- -->i think so<br>
<!-- -->yeah</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i want to kind of address the big question to start with, about WHY. in some respects<br>
<!-- -->we don't really want to create open.mp - we were perfectly happy playing samp, it's a nice little game, it does everything we want, but kalcor wrote it, he has the source code and<br>
<!-- -->things, he had some help, and in short he was no longer interested in maintaining it which is fine and happens to everybody, and i just want to make that clear that i've no hard feelings to him for that because everybody moves on eventually, you get new interests but<br>
<!-- -->he decided that he wanted to just take everything down with him. he didn't want to pass on the source code, he just wanted to stop so he felt everyone else should stop as well. and we quite liked it here so we didn't stop.</p>
<p><strong>Potassium:</strong><br>
<!-- -->correct</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah that sounds fine</p>
<p><strong>Y_Less:</strong><br>
<!-- -->as i said, if he wants if he wants to move on and move on to other things that's only his prerogative</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes that's right, we're not judging, we're just a little bit sad. but that's okay, because we're gonna fix it. we can do something about it so we will!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah let's move on to the next bigger things</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah that's right. alright so we had a bunch of questions on our forum, which by the way is<br>
<a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp</a> so sign up there!<br>
<!-- -->so i guess let's just get into them.<br>
<!-- -->the most pressing question right now obviously is regarding the recent samp drama. so for those who don't know the samp forum and the samp wiki have been offline for a few weeks now, and we don't want to make assumptions but it doesn't look like they're coming<br>
<!-- -->back anytime soon. i think that's a pretty fair assumption to make.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->the links have been removed from the home page, if it was just a temporary thing he<br>
<!-- -->would have probably not removed the links.</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah that's right, so it doesn't look like they're coming back. so people just kind of want to know what our thoughts are on this, what do we think actually happened? so... open mic... <strong>Southclaws</strong>? anyone?</p>
<p><strong>Y_Less:</strong><br>
<!-- -->it's basically what i just said, kalcor has for years been uninterested, that's why there's<br>
<!-- -->just been zero development, and several of us when i was in the beta team kept trying to push him along and release updates and things, and actually the whole community was screaming for updates, he didn't want to because he'd lost interest, he wanted to move on and that's... as i already said that's fine, we don't mind people moving on and leaving<br>
<!-- -->projects, it was the fact that he refused to hand over the reins to anybody else, this is just a<br>
<!-- -->continuation of that, the forums were pretty huge, they were not easy to run, it's close to a full-time job just moderating them. and i suspect he's just totally lost interest and decided he no longer wants to do it, but does not want anybody else to continue his legacy, so he's just taking everything down. i'm slightly confused that the home page is still there.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i'd imagine that's probably just because the home page probably costs next to nothing to actually keep online, whereas the forum probably took a bit of time and expense to<br>
<!-- -->actually run. i'd imagine that's why.</p>
<p><strong>BigETI:</strong><br>
<!-- -->you can still download samp from the main home page</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah that's good, at least they can do that. but if we complete our mission<br>
<!-- -->they won't have to!</p>
<p><strong>Potassium:</strong><br>
<!-- -->personally i just hope kalcor is ok! what if he got COVID and he's in the hospital and can't maintain</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that would be really bad</p>
<p><strong>Potassium:</strong><br>
<!-- -->what if it just like ran out and he can't put it back up because he's in hospital</p>
<p><strong>JustMichael:</strong><br>
<!-- -->that would just be extremely unfortunate</p>
<p><strong>Potassium:</strong><br>
<!-- -->and then he comes back and there's just like... a mutiny... anyway</p>
<p><strong>JustMichael:</strong><br>
<!-- -->and while he was in hospital he happened to remove the forum link and wiki...?</p>
<p><strong>Potassium:</strong><br>
<!-- -->oh yeah... fair enough</p>
<p><em>everyone laughs</em></p>
<p><strong>Y_Less:</strong><br>
<!-- -->i'm just thinking we might have heard about that</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah we probably would've heard about that, you're right</p>
<p><strong>Y_Less:</strong><br>
<!-- -->or maybe not because even beta testers barely hear anything, i can speak from<br>
<!-- -->personal experience, people kept asking me when is the next version coming out?<br>
<!-- -->i know just as little as you do. but we have our own private forum and it's dead.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->he ended up being pretty bad at communicating anything to any of the devs</p>
<p><strong>Potassium:</strong><br>
<!-- -->time to move on. on the subject of forums, our forum and our wiki seem to be quite popular replacements for the samp ones so feel free to check them out</p>
<p><strong>Y_Less:</strong><br>
<!-- -->they are not dead</p>
<p><strong>JustMichael:</strong><br>
<!-- -->they're very active and maintained, more than i've ever seen</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah, particularly for scripting help</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah the wiki contributions have been great, when the wiki went down, having<br>
<!-- -->loads of people just copying pages from the old wiki onto the new one was really good, so shout out to everyone who contributed, thank you, that was really cool. the translation stuff is great because i think that's one thing that the old wiki definitely lacked, it had a handful of pages that were translated but not many i think.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i think it was like polish, brazilian, and... yeah... we lacked a lot.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah translating that is a definitely a priority and we've got some good people to help us with that so that's brilliant</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah that's awesome. just for the record, <a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp</a> is our forum and <a href="https://open.mp/docs" target="_blank" rel="noopener noreferrer" class="">https://open.mp/docs</a> is our wiki, so go there!<br>
<!-- -->so obviously the next discord alert noise that scared me, sorry! the next most frequently asked question is and always will be is the release date. so obviously we don't have a date, we will never give a specific date because we're all volunteers and do this in our free time, but do we have a rough idea of maybe like a percentage of how far along we are before we can make it public? are 1% through? are we halfway through? are we 90% through? what do you think?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i mean, we're pretty close aren't we?</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah i think most of our big systems, the bulk of it, is done. they say that the first 90% takes 90% of the time, and the last 10% takes the other 90% of the time because it's all that kind of tweaking, and there's bugs, and when this and this and this and this happen together, suddenly everything breaks. most of what we've called "modules" are done now, i can explain modules later, but essentially the large chunks of code are done now. it's just connecting them making sure all the little extra features are there. it's progressing fairly steadily, now especially recently,</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah we've had quite a bit of a big boost of active development recently which is very nice</p>
<p><strong>Potassium:</strong><br>
<!-- -->i was just gonna ask if anyone else had anything else to add to that</p>
<p><strong>j0sh...:</strong><br>
<!-- -->i think it depends on what you define as public, i can pretty much say that we're fairly close<br>
<!-- -->to having a beta test server, i'm sure we're near that. but a public release as in everyone else having the executable is obviously a bit further off, but i think a test server will be coming fairly shortly.</p>
<p><strong>Potassium:</strong><br>
<!-- -->woohoo!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah we need a fair amount of time to test all the progress so far because there's still gonna be edge cases</p>
<p><strong>Potassium:</strong><br>
<!-- -->did you hear that chat?! a test server is coming fairly shortly! mark his words!<br>
<!-- -->alright so most of the questions from this point on are from a scripting point of view, so obviously i have no idea about that stuff so this is where you guys shine! so you mentioned modules just before, did you want to explain that a little bit? or did you not want to?</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah basically modules is an extension of kind of a general trend in library development and stuff that has developed over years, for code isolation, so all the objects, all the code related to objects, that's a module. all the code related to checkpoints, that's a module. vehicles is a separate module.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so in terms of plugins and filter scripts like we have in samp, is that what we're... are we renaming them to modules? i think i saw something about that before but i don't understand that stuff!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->not quite, modules are more like a chunk of code that provides some functionality, so your filter scripts... i mean, we don't really have filter scripts anymore, we just have scripts, because game modes and filter scripts was an arbitrary pointless distinction in the first place. we do still have plugins but there's legacy plugins which is all existing ones,<br>
<!-- -->most of them should work, some of them won't.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->any memory hacking ones won't</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yes, if they use memory hacking they won't work because that's just changing values in memory at very specific locations, but because it's completely different code, everything's<br>
<!-- -->moved</p>
<p><strong>BigETI:</strong><br>
<!-- -->yeah but then but then if someone wants to make let's say a memory hacking plug-in to work on openmp, they can just use the existing api in openmp instead of hacking memory</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah you won't need to go about that route anymore</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah so we have a full C API, so legacy plugins had about 3 functions that they could call in the server, and that was it. and there were all sorts of workarounds and horrible ways to<br>
<!-- -->put natives from plugins, now you can do that directly so 90% of the need for memory<br>
<!-- -->hacking plugins is just gone. things like samp gdk, that was just pulling pawn<br>
<!-- -->functions from plugins, that's gone. the plugins are all these legacy ones, and modules are basically the replacements. like plugins, but far more powerful.</p>
<p><strong>Potassium:</strong><br>
<!-- -->cool. i'm just smiling and nodding because i don't understand but i'm sure most of our viewers do so that's awesome!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->if anybody wants any clarification on that, just ask! maybe you're in the same boat as Potassium</p>
<p><strong>Potassium:</strong><br>
<!-- -->correct! so obviously we've got our forum for questions like that, but also we're going to have a little live question session at the end so stick around!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->it's also not like we won't document the code when it's actually released, so you know if you are struggling to understand what any of this is, we will have some kind of explanation that just tells you what it is.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so we got a few questions about limits, i know that we've we talked about that in our last Q&amp;A, and i think you guys said there won't be limits on things like vehicles and objects, is that right?</p>
<p><strong>BigETI:</strong><br>
<!-- -->there is no reason to have arbitrary limits, but right now openmp will be just a server release for now</p>
<p><strong>Potassium:</strong><br>
<!-- -->server release</p>
<p><strong>BigETI:</strong><br>
<!-- -->so you have to make it competitive with san andreas multiplayer, therefore we<br>
<!-- -->have to emulate limits, but then internally in openmp there are no server-sided limits. it just depends on how much your machine is capable to do</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah so it does appear that in the very first version that the limits will be have to be in place<br>
<!-- -->until we get our own client out</p>
<p><strong>Y_Less:</strong><br>
<!-- -->an internal streamer</p>
<p><strong>BigETI:</strong><br>
<!-- -->we can't go over game limits right now</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah that's true yeah</p>
<p><strong>Y_Less:</strong><br>
<!-- -->there was one interesting issue with limits that we were discussing last week, the server itself can stream players as well, so in theory you could have unlimited players on the server even with this legacy samp client, basically we just send the players closest to you, sync them, and then when you move further away we change which players are synced. but we've had to disable that by default because it means that everybody's constantly<br>
<!-- -->changing IDs, so i would connect to the server and have a server ID of 27, but when i'm streamed to you i have your local ID of 3. i'm streaming to somebody else and i have a<br>
<!-- -->local ID for them of 17. so you as an admin see that i'm cheating and type /ban 5 because you think that i'm ID 5 but the server thinks i'm ID 27. and translating those when people are just using raw IDs instead of names is tricky. we've decided to disable that for now and<br>
<!-- -->make it optionally enabled if people want it, but with the caveat that their script will need to be aware of this and for example if in a command they just use strval to get typed ID, don't do that because it would probably be wrong, or do do that and then translate it to from local ID to server ID. sscanf will probably support that already, but if you do type "u", if you<br>
<!-- -->use sscanf with "u" already it will auto translate. some scripts will need updating to support that.</p>
<p><strong>Potassium:</strong><br>
<!-- -->actually the next question was "will we still be limited to 1000 player slots?" so i guess that kind of ties in.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->the answer for that is no!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->if you enable it</p>
<p><strong>BigETI:</strong><br>
<!-- -->i wanted to add to that, so our idea is to have like, you can configure what you want to limit<br>
<!-- -->for yourself, because for example you don't want a server where you can spawn infinite entities, because someone could abuse it and just down your server, so there should be some configuration you can do to limit stuff, like players or vehicles or something else.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah fair enough</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i just want to say that's not me in the twitch chat</p>
<p><strong>Potassium:</strong><br>
<!-- -->it's ok i banned them, that is not the real Y_Less: in chat, THIS is the real Y_Less:!</p>
<p><strong>BigETI:</strong><br>
<!-- -->what is your twitch account Y_Less:?</p>
<p><strong>Potassium:</strong><br>
<!-- -->it's ok, it's not important. so moving on with the community questions, people want to know which languages other than pawn we can script our servers in.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->that's completely dependent on plug-in developers, we already have quite a few already which can be easily ported over, and some already do work, i think bigeti you were working on or at least you were thinking about writing another C# one right?</p>
<p><strong>BigETI:</strong><br>
<!-- -->i was thinking to implement some module that implements another language like for example C# because nowadays C#... well first of all i don't want to say that it will be officially supported, but i'm thinking about making a module so it will be released under my name.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i know there's the sampnodes, that's amir, and i also help on that sometimes so that should be easy to poty over if it doesn't already work.</p>
<p><strong>BigETI:</strong><br>
<!-- -->i think it already works with openmp, it would be better and faster if we use the C API that we are providing for openmp so it's better than going through the pawn layer</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah well we'll have to find a way to translate the rust plug in over somehow, or the rust sdk, to make that work</p>
<p><strong>Y_Less:</strong><br>
<!-- -->samp gdk?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah we're gonna find a way to support the current rust plugins</p>
<p><strong>BigETI:</strong><br>
<!-- -->no more fake amx bollocks</p>
<p><strong>Y_Less:</strong><br>
<!-- -->a lot of those plugins use samp gdk to access pawn, we just need to change the lowest<br>
<!-- -->level in there</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah the rust one doesn't... he just kind of tried to reinvent it in his own way</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i don't think the rust community is that big</p>
<p><strong>JustMichael:</strong><br>
<!-- -->there are a couple of plugins that people do rely on</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah i might take a crack at that, i don't know, but it'd be cool to write modules in rust i think, shouldn't be too difficult.</p>
<p><strong>Potassium:</strong><br>
<!-- -->cool, ok, next question: will sampCTL/openCTL be the official package manager for open multiplayer?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that's my ballpark! yes it will, it will be renamed of course, yeah it's going to<br>
<!-- -->be Open Packet Manager - OPM.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->that's what we decided on</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that's what i decided on!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i gave you the name!</p>
<p><strong>Southclaws:</strong><br>
<!-- -->we're kind of working on experimental features at the moment, i've sort of just built a couple of quick interesting experimental things for that, they're coming in the recent days, i've been coding, so yeah i'm thinking mainly about developer experience type things so<br>
<!-- -->things like logging and command line interface environment variables, you know, all the stuff that helps you kind of build game modes faster and deploy them faster and automate as many things as you can. such as the deployment process and that sort of thing so<br>
<!-- -->yeah that's where my head is at really. some CTL will remain compatible and will basically just add openmp support. so you can switch to it just by changing a string, in theory, and changing your includes and then recompile and it'll just work. that's the plan anyway!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->that's gonna be a lot of fun!</p>
<p><strong>Southclaws:</strong><br>
<!-- -->and then it'll eventually have a bunch of new features as well, better log handling, better docker support, better deployment automation, stuff like that, some of which will be implemented into openmp itself, a lot of the things that sampCTL does is actually to<br>
<!-- -->get around awkward design choices with the samp server, so a few of those things<br>
<!-- -->won't need to happen, a few of them will just be implemented directly into openmp. so yeah hopefully that answers that</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yes sampCTL/openCTL is officially supported, officially endorsed, probably distributed with it, but that doesn't mean it's required, you can write scripts without it, if you don't know how then you don't have to start using it</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah it's kind of like how you can use node.js without npm</p>
<p><strong>Potassium:</strong><br>
<!-- -->cool, ok, next question: what are openmp's current build times?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->does that mean the C++ build times or script?</p>
<p><strong>Potassium:</strong><br>
<!-- -->i don't know</p>
<p><strong>Southclaws:</strong><br>
<!-- -->we could just do both because they're both questions we can answer</p>
<p><strong>BigETI:</strong><br>
<!-- -->if you rebuild the entire project, make sure to make a coffee then! click compile, make a coffee, come back and it will be done.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->it's gotten way better, it used to be like half an hour, now it's about eight minutes.<br>
<!-- -->i spent a lot of time improving that. the player module used to be everywhere, included by everything, if you accidentally touch that file that's a full rebuild. change one line, that's a full<br>
<!-- -->rebuild.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->as for scripts, that shouldn't change too much really. we have a compatibility layer, scripts will just be the same, i think there is a question about that later on so i'll leave that until then.</p>
<p><strong>Potassium:</strong><br>
<!-- -->alright, cool, thank you. next question is: a lot of people wanted to know if we'll have a built-in anti-cheat?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->no, i think we'll have a kind of very small... not really an anti-cheat but more of<br>
<!-- -->just like we will try to block a few known issues, exploits, stuff like that, but i think we're going to leave it to other developers</p>
<p><strong>Southclaws:</strong><br>
<!-- -->we'll provide people the tools to build good anti-cheats, that's probably the most efficient way because then the community can come together and build solutions for specific cheats. because if the community is dependent on us for doing that then it's just going to get overtaken because the amount of people developing cheats is going to outnumber the amount of people developing openmp</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i'll probably post an official kind of repo for one where anybody can contribute, and serve it as a module, because the idea is that eventually... well, it's called openmp, it's meant to be open source. it's not currently because we've not finished the first release, but once it is,<br>
<!-- -->then we can release it and other people can contribute, and that's one of the major areas where we're hoping they will do. so will it have an officially included anti cheat? yes, if you help us!</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah, that's what it comes down to really, if the community helps then yeah we'll have things like that!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->a lot of people forget that samp did have one, they experimented with an anti cheat for a while, and by a while i mean about a month, before it just became completely unfeasible because oh look they've blocked this cheat, it took us seven seconds to get around it, now<br>
<!-- -->you have a new cheat. it's a constant game of cat and mouse.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i feel the anti cheat should be separate, because we won't be updating the mod that much, we don't want to be updating every day or every week, it's going to be more of a long-term thing, but an anticheat needs to be updated quite frequently to combat the cheats so<br>
<!-- -->having it as a separate module or something like that would probably be better for servers than having to rely on us waiting for us to release at the end of the month or however<br>
<!-- -->long our update process will be</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah that's kind of what i meant about boosting it centrally</p>
<p><strong>Potassium:</strong><br>
<!-- -->so if we just have it open then everyone can contribute and then it's not entirely on you guys to keep it updated and stuff. and then on that note, CLEO mods, a lot of people want to know if they'll still work, or mods in general</p>
<p><strong>JustMichael:</strong><br>
<!-- -->they're all client-side</p>
<p><strong>j0sh...:</strong><br>
<!-- -->there'll be no changes</p>
<p><strong>JustMichael:</strong><br>
<!-- -->not in this version anyway</p>
<p><strong>Y_Less:</strong><br>
<!-- -->um so unless they start cheating in a way that the server can detect</p>
<p><strong>Potassium:</strong><br>
<!-- -->ok, people wanted to know if openmp will have a fixed GPCI function like a serial in MTA</p>
<p><strong>JustMichael:</strong><br>
<!-- -->the problem with that is it's never going to be a 100% guaranteed way of banning someone or finding out if that player is that player, because anyone with any kind of skills at all will just use some kind of modifier for their system and they will just change some information and then they've got a brand new ID so there's not really much we can do with<br>
<!-- -->that, we can we can provide you the tools, but i can't say they're ever gonna be 100% working.</p>
<p><strong>Potassium:</strong><br>
<!-- -->cool, anyone got anything else to add to that? nope? okay cool</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i do have something to add on the AC side of things since people are asking about that a bit more. so we definitely can't have a general ban system because servers are independent. if one server wants to keep you and one sever wants to ban you, that's<br>
<!-- -->up to the server. if one server wants to let you keep cheating that's up to the server.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i used to play a cheating server and it was really fun, i just want to add that</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah so a global ban list wouldn't work for reasons like that</p>
<p><strong>Y_Less:</strong><br>
<!-- -->oh that's a terrible idea, i know other mods have done it, that doesn't mean it's a<br>
<!-- -->good idea. as for the anticheat itself, it will be separate and yeah you can update it at any rate you like.</p>
<p><strong>Potassium:</strong><br>
<!-- -->awesome. alright we got a lot of questions about raknet, i think people just want to know what your thoughts are on it, if openmp will use the same version that samp uses, blah blah blah</p>
<p><strong>j0sh...:</strong><br>
<!-- -->there's a minor difference but nothing extraordinary, we need basically the same major version for it to actually communicate with samp perfectly</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah the compatibility layer for communicating with existing samp clients is basically the same.</p>
<p><strong>iAmir:</strong><br>
<!-- -->it's going to be changed, right? so it's going to be changed later, for example when openmp client gets developed we're going to add a new networking library so for example other networking library out there, each one of them is probably better than raknet, especially the version that we are using right now. so yeah for now we're going to use<br>
<!-- -->raknet as the same version that samp is using, only to keep the backward compatibility. other than that for example for NPCs that josh is working on right now, i mean not right now but he was working on it, but he was using enet, that's probably, our first choice and it's way much better than raknet, and it gets contributed to more frequently, so we do not have issues with exploits or stuff that come up later because we all know that raknet project is<br>
<!-- -->dead, the latest version is probably six years old by now. so that's the only reason that we're using raknet now, we're gonna change that.</p>
<p><strong>Potassium:</strong><br>
<!-- -->cool, i don't understand any of that, but thank you. so there was a lot of discussion in<br>
<!-- -->the thread about sync and c-bug and stuff like that, so i guess people want to know what the sync will be like compared to samp</p>
<p><strong>JustMichael:</strong><br>
<!-- -->the exact same</p>
<p><strong>j0sh...:</strong><br>
<!-- -->exactly the same yeah. we'll see, but we can't do that until the client comes out, and i'm probably not going to do that because that's ruining the experience of samp.</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah so there was a lot of debate about that, and obviously there is within the team<br>
<!-- -->as well.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah i wouldn't agree with that because my server literally relies on those bugs</p>
<p><strong>Southclaws:</strong><br>
<!-- -->people enjoy that stuff and there's already ways to stop it and prevent it anyway so i don't really think it's our prerogative to get involved in that</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i think that in the client we should probably have a way to disable those kind of bugs if the server owner wants to, but it should be an option</p>
<p><strong>Southclaws:</strong><br>
<!-- -->you can disable it via pawn scripts anyway</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah you can</p>
<p><strong>Potassium:</strong><br>
<!-- -->so the consensus on that, just to clarify, is that we are just going to leave it how it is and<br>
<!-- -->each server can choose what they do with it. is that right?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->pretty much yeah</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah pretty much</p>
<p><strong>Southclaws:</strong><br>
<!-- -->it's one of those things where you're damned if you do, and you're damned if you don't, so yeah</p>
<p><strong>Y_Less:</strong><br>
<!-- -->again it's up to servers. servers are different so if they want it, they can have it</p>
<p><strong>Southclaws:</strong><br>
<!-- -->kind of like lag comp, some people like lag shot, some people don't like lag shot, which is why it was an option you could turn on and off</p>
<p><strong>Potassium:</strong><br>
<!-- -->that's right yeah, i think that's the best way to go about it. ok so a very popular question both on the forum and in this chat which i know you guys don't want to answer but we're gonna do it... samp for android. what are your thoughts on that?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->we're not gonna support it directly, but we're gonna give the tools so that anyone else<br>
<!-- -->can do it</p>
<p><strong>Southclaws:</strong><br>
<!-- -->we don't want to support the existing samp mobile, because the existing current<br>
<!-- -->version of samp mobile is based on stolen code. it's very not legal.</p>
<p><strong>BigETI:</strong><br>
<!-- -->someone here probably wants to use openmp and then make their own android clients</p>
<p><strong>Potassium:</strong><br>
<!-- -->so officially as open multiplayer developers, NO is the answer?</p>
<p><strong>iAmir:</strong><br>
<!-- -->there is actually some stuff blocking us, for example to implement our own library into an APK file we need to modify that, so that means we need to modify GTA SA apk<br>
<!-- -->file for android, and that actually has legal issues. so besides that, we'd actually need<br>
<!-- -->to modify some code in gta apk file too, so either going to be the java assembly or<br>
<!-- -->we'd patch the current gta sa code, so that would load our own library which would be openmp client, so for that as i said we'd need to modify the game. and we'd need to give people the modified version, which is not legal, so we would have issues legal issues later, copyright issues later.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->technically we could legally distribute the binary to players and then let them add it to their apk</p>
<p><strong>Y_Less:</strong><br>
<!-- -->there is stolen versions of the source code out and about, so that's what the android<br>
<!-- -->version is based on. if we wanted to use that we could have used that, we could have<br>
<!-- -->started from that code, updated the server, and written openmp using stolen code,<br>
<!-- -->and it would have been very illegal and that's entirely the reason why we started openmp from scratch, zero old source code in it, you can compare them and they are absolutely nothing alike. because we do not in any way condone stealing.</p>
<p><strong>Potassium:</strong><br>
<!-- -->correct, that's a very important point to reiterate, we do not support stolen code</p>
<p><strong>Y_Less:</strong><br>
<!-- -->and there is NONE in this mod.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->it would potentially put us in a really bad spot with legal issues if we were to go down that route anyway</p>
<p><strong>Y_Less:</strong><br>
<!-- -->it would've been out years ago if we did!</p>
<p><strong>Potassium:</strong><br>
<!-- -->now along a similar path of questions, people want to know why they should play openmp instead of mta. so without without insulting other mods, what's different?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->well we're still offering the same samp experience that everyone loves, but i guess we're now offering an upgrade path. more features down the line, a possible path for everyone to kind of like move forward, even add the stuff that everyone's wanted from samp for years. a lot of people have left samp because samp has been down the same path for a very long time, it's not gone anywhere, very little has been added. but now we're giving people the opportunity to add what they want now, after we've released it, they can add stuff you and that path's open now.</p>
<p><strong>Potassium:</strong><br>
<!-- -->anyone got anything else to add?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->mta is great, i like mta. mta's not a bad software, there's no beef there, the map editor is great! i always used to use it. but there is a cultural difference between mta and samp, and i don't think anyone's really managed to figure out what it is exactly. mta definitely has better features, it is an objectively better thing than samp, but people just kind of like samp more, i guess it stays close to the game.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->they have different goals</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah different goals, mta kind of feels more like garry's mod in a way. it's more of a sandbox type create your own crazy multiplayer game type thing</p>
<p><strong>Hual:</strong><br>
<!-- -->people like simplicity</p>
<p><strong>Southclaws:</strong><br>
<!-- -->and the ability to join the server without downloading 500 megabytes of anime skins is always a good thing!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i guess samp and mta serve slightly different markets, why you'd use this one instead of mta is the same reason why you'd use samp instead of mta - it's essentially samp.</p>
<p><strong>Potassium:</strong><br>
<!-- -->the next lot of questions are more about the structure of the mod and the community rather than scripting. so people would like to know if it will be compatible with the steam version of san andreas because obviously, as we know, samp is not.</p>
<p><strong>Hual:</strong><br>
<!-- -->it should be.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah, mta does it, i'm sure we can do it</p>
<p><strong>j0sh...:</strong><br>
<!-- -->it will just take a lot of work.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->there's no reason not to.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->but if not, there are downgraders anywa,y and there's been downgraders for years. so either way it's not a huge issue i don't think.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->no but we should be able, there's really no reason not to</p>
<p><strong>Potassium:</strong><br>
<!-- -->well that's that's exciting!<br>
<!-- -->ok now the master list. people want to know what's going to happen with that, will we have a<br>
<!-- -->paid list, etc. etc. - the server list</p>
<p><strong>JustMichael:</strong><br>
<!-- -->we have a few ideas for it but i'm not sure, we've not gotten to that point where we've gone "okay this is what we're doing"</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i want to reiterate that this is not a for-profit project at all. there have been ideas thrown around, because people actually do genuinely want a way to... you know, if they run a big server and it is kind of like a business, then they do want a way to kind of bump it to the top like an investment kind of thing, and i appreciate that and i've actually talked to quite a few people about that desire from the sort of larger server community, there are ideas and i don't think we're quite ready to discuss them all yet because they're not really fleshed out. but i have been working on the new server index which is currently being deployed. it's essentially going to be like samp-servers.net but with an updated backend, and it'll support samp servers and in future openmp servers, and it's kind of going to be like the advertisements board from the forum, but better because it's not on a forum, but yeah it'll be like a dedicated website and it'll be openmp servers or something like that, and that will come soon. the first version is kind of done, and that will be open source as well, so you kind of follow along the development of that and eventually that will turn into the list. as i said we're quite early on decisions like that, and i don't really know what the team's consensus is, but i think we're probably not going to split servers into two separate lists because that just kind of separates people into the bad ones and the good ones in a way, and it kind of creates us versus them sort of... not a conflict, but just like a, you know, it's kind of like a separation</p>
<p><strong>Y_Less:</strong><br>
<!-- -->a divide</p>
<p><strong>Southclaws:</strong><br>
<!-- -->and i think giving the smaller servers a chance to kind of get some visibility is good as well because sometimes people make a really cool project and maybe they can't pay to go onto the hosted list or whatever, so one of my goals in that is to kind of surface potentially interesting servers that don't have reach. but at the moment it's just going to be like a list and you can sort it by whatever you want and find servers. that'll be the first version.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah samp at the moment is very biased for its hosted tab</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah, and it's limited and expensive</p>
<p><strong>BigETI:</strong><br>
<!-- -->yeah and it's a horrible name</p>
<p><strong>iAmir:</strong><br>
<!-- -->for our own server list we can actually add some options like ratings, voting and stuff like that, so like there can be two sections for example uh one could be the ones with most ratings, and the other could be for example a server that got rated frequently, in recent days, so we can actually see the trends and stuff like that. so new servers can go up and can be seen by other players. so that's actually a good way for new servers that have actually a unique idea so they can actually be seen by other players and get famous, it's actually a better way than spending money on some other lists or stuff like that.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so i think the really important thing to take away from that is that we are a not-for-profit project, so we're not gonna create a server list purely for the intention of making money off of it.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->but that doesn't mean there won't be ways to advertise. and if you have ideas about thatm post on the forums!</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes, and that is <a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp</a> - sign up!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->that's something we've discussed for like two years and we have no conclusion</p>
<p><strong>Potassium:</strong><br>
<!-- -->ok, someone asked: does the openmp server actually include any kind of performance upgrade compared to the samp server? i think we sort of answered that before in the mta question but if anyone has anything else to add to that...</p>
<p><strong>Hual:</strong><br>
<!-- -->yeah can i just say i've actually run it on a raspberry pi zero, so yeah</p>
<p><strong>iAmir:</strong><br>
<!-- -->yeah you can host your own server while you're walking down the street, you have your raspberry pi in your pocket and still running your samp server so yeah it should be fast that this can be possible</p>
<p><strong>JustMichael:</strong><br>
<!-- -->should we mention because we're using C++17 and there is like a minimum deployment for that, right?</p>
<p><strong>Hual:</strong><br>
<!-- -->what do you mean?</p>
<p><strong>Y_Less:</strong><br>
<!-- -->no? depends how you build it</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i mean like library requirements as in like system operating system libraries and stuff like that</p>
<p><strong>Southclaws:</strong><br>
<!-- -->Glibc and stuff like that</p>
<p><strong>BigETI:</strong><br>
<!-- -->it shouldn't be a problem</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah there's no reason why you can't build it for a different system</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah you're probably right yeah i'm thinking of edge cases like ark and stuff, but that'll probably work anyway... wait didn't someone actually build it for ark already? oh maybe that was you Hual? maybe that was you doing it for me?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->oh you mean arm?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->sorry yeah i said ark didn't i?</p>
<p><strong>Hual:</strong><br>
<!-- -->so yeah performance isfine, compatibility is fine</p>
<p><strong>Potassium:</strong><br>
<!-- -->now the question everyone hates... 0.3 DL. a lot of people, a lot of server owners asked if<br>
<!-- -->if it will be compatible on first release so they can instantly switch their servers over.</p>
<p><strong>everyone:</strong><br>
<!-- -->yes</p>
<p><strong>BigETI:</strong><br>
<!-- -->that was easy</p>
<p><strong>Potassium:</strong><br>
<!-- -->that WAS easy because the last time we talked about it we had very divided opinions and we kind of just asked the community what their opinions were,</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah well we already know it's possible because adrian graber wrote that plugin that literally tricks the client into connecting so we know we can do it</p>
<p><strong>Potassium:</strong><br>
<!-- -->and then, on a similar path, i know we're not taking live questions yet but someone in chat had a really good question: have you guys thought about making a workshop for openmp something like how mta has for maps, scripts, plugins, etc?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->uh that would be really cool!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah that would be cool!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->the question is have we thought about it? the answer is no. but now we will!</p>
<p><strong>Potassium:</strong><br>
<!-- -->so thank you! moving on, people wanted to know more about future plans. so a specific question was "what's the next step for openmp after it reaches samp flow" - so once we've we've got it to compatibility and where we want it to be, what are your future plans and ideas?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i think after release we're just going to try and start with the client, just head for the second release i guess. we haven't really thought about it too much.</p>
<p><strong>Hual:</strong>
we should probably fix up the server first</p>
<p><strong>JustMichael:</strong><br>
<!-- -->we'll probably have a time frame after we've released where we wait for bug reports<br>
<!-- -->and stuff and handle that, because in any software there's always going to be those edge cases that need to be sorted, and no software that comes out the gates on the first try is<br>
<!-- -->ever going to be perfect.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so is it fair to say the the initial release, and for a while after, won't really see any new features, they'll come later in the future maybe?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->oh yeah probably not straight away</p>
<p><strong>j0sh:</strong><br>
<!-- -->we're basically limited by the client so without our own client we can't really do much</p>
<p><strong>Y_Less:</strong><br>
<!-- -->we can do some clever things, we've got some tricks up our sleeves</p>
<p><strong>Potassium:</strong><br>
<!-- -->watch this space, basically!</p>
<p><strong>BigETI:</strong><br>
<!-- -->but most of them have already been done in one way or another</p>
<p><strong>Potassium:</strong><br>
<!-- -->well there's always something new i think. on that note, what kind of things would you guys like to eventually add once it's all compatible and bugs are all sorted and everything, new things that you guys would like to see?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->sex animations.</p>
<p><strong>Potassium:</strong><br>
<!-- -->oh my god.</p>
<p><em>everyone laughs</em></p>
<p><strong>j0sh...:</strong><br>
<!-- -->I want unicode. I want the clown emoji in chat.</p>
<p><strong>Potassium:</strong><br>
<!-- -->oh yeah emojis in chat!!!</p>
<p><strong>Southclaws:</strong><br>
<!-- -->the ability for russian people to talk to english people on the same server without having to change the code page</p>
<p><strong>JustMichael:</strong><br>
<!-- -->yeah that would be nice</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that would be great</p>
<p><strong>j0sh...:</strong><br>
<!-- -->that's revolutionary</p>
<p><strong>Potassium:</strong><br>
<!-- -->that is revolutionary!</p>
<p><strong>Southclaws:</strong><br>
<!-- -->multi-server clustering would be cool, there's a lot of russian servers out there that run like 20 servers and they're all connected and you can imagine it's very janky in the back end. i think facilitating that would be kind of neat, to be able to switch server in game and stuff like that.</p>
<p><strong>Potassium:</strong><br>
<!-- -->someone in chat just asked: voice chat in openmp?</p>
<p><em>everyone laughs</em></p>
<p><strong>Southclaws:</strong><br>
<!-- -->do you want 12 year olds shouting at you down the street? i don't think so. there are plugins out there, and of course with the client and the server out in the future, if you want to do voice chat like plug-ins then go wild!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->there are quite a few on there already, i think i know two already</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i think they're closed source though so it's kind of sketchy</p>
<p><strong>JustMichael:</strong><br>
<!-- -->no i think i think one of them is open sourced</p>
<p><strong>Y_Less:</strong><br>
<!-- -->there's one actually open source</p>
<p><strong>Southclaws:</strong><br>
<!-- -->well there you go, that's the solution. i think one thing i do want to say though is just because we're making a from scratch new multiplayer mod platform to build on, that doesn't mean that the actual mod itself has to have every single possible feature crammed<br>
<!-- -->into it. we're making a better plugin api for a reason, we get questions like are you going to add mysql or are you going to add sscanf, or are you going to add this plug-in to that plug-in, and most of the answer to those questions is no, because there's no reason to. in fact there's more reason to build more things as plugins because then they're modular, you can add and remove them when you don't need them. so i think the same goes for things like<br>
<!-- -->voice chat and client things. we'll provide a better set of tools for people to actually augment the experience and add new things to it, and i think that's better than cramming<br>
<!-- -->it full of features that maybe most people won't actually use.</p>
<p><strong>Hual:</strong><br>
<!-- -->yeah but also since installing plugins in samp is kind of annoying, we probably should think about having an official plugin registry where servers can actually specify what client plugins the clients download</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah like a client version of sampctl i suppose. and of course the worry there is always about being able to run arbitrary code on a user's computer so you know i think having a repository would be kind of good</p>
<p><strong>Y_Less:</strong><br>
<!-- -->just something to bear in mind, half of the big plugins that everybody uses like mysql, streamers, sscanf, all that, the developers for those plugins are ON THIS TEAM! we're not just going to stop developing them and say you can't get my plug in now because i wrote<br>
<!-- -->something else.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so can we just clarify for some people asking in chat about making a client. so that's<br>
<!-- -->that's a future plan, right? making our own client?</p>
<p><strong>everyone:</strong><br>
<!-- -->yes, that's the second version</p>
<p><strong>Southclaws:</strong><br>
<!-- -->that's the fun part</p>
<p><strong>Potassium:</strong><br>
<!-- -->people were asking about other communities that speak different languages and such, and they kind of want to know what we're doing to work with those communities and how we plan on spreading the word to those communities. i think it's fair to say that we're working on that, we're recruiting volunteers i guess to translate our wiki pages and whatever else to other languages, to moderate language sections on the forum, <a href="https://forum.open.mp/" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp</a> by the way, and generally just to be the point of contact between our team and the other communities i guess</p>
<p><strong>JustMichael:</strong><br>
<!-- -->we've made a huge effort already to translate the wiki, so we're making an improvement to<br>
<!-- -->make it easier for those communities to combine with the larger community. i myself<br>
<!-- -->have already talked to quite a few because i know quite a lot of balkan area servers, i<br>
<!-- -->actually run one even though i don't speak the language, but there you go. i actually run a second one now, and a role play server, so i've been in touch with quite a few of their areas and tried to get quite a few of them over and a lot of them are on board, a lot of server owners from those areas are on board, so that's that's always good</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i was surprised to know there's quite a big chinese, japanese, taiwanese community as well that i didn't even know about, so i've been talking to people in those communities<br>
<!-- -->and helping translate and stuff.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i found out that there was a big chinese and japanese community about seven seconds ago when you said that</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i've mentioned it before in the discord but yeah there is actually a big community, the problem's always been the language barrier, but the translation stuff is really helping with that the fact, that you can actually do it, because the old wiki you couldn't create an<br>
<!-- -->account for many years for some reason, so no one could translate the wiki</p>
<p><strong>Y_Less:</strong><br>
<!-- -->the reason is kalcor</p>
<p><strong>Southclaws:</strong><br>
<!-- -->so people usually make their own wikis and stuff and they got outdated and yeah, problems and problems. i have heard apparently in thailand there's actually a single translated version of the godfather game mode that everybody copies and uses</p>
<p><strong>Y_Less:</strong><br>
<!-- -->there are already multiple language sections on discord, and the forums. the big issue that we had, because the samp forums used to have language sections as well, the problem<br>
<!-- -->was moderating them because if we don't speak the language we don't know what you're saying. if there's issues people make reports like oh this person's doing something bad.<br>
<!-- -->well we don't know, we can't review that really, so we'd love to reach out to communities,<br>
<!-- -->we kind of need people within those communities that speak english to liaise with, but we're very interested in finding those people who are involved in one of the foreign<br>
<!-- -->language communities, and speak english, please speak to us!</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah so if you know trustworthy members of the community who speak other languages and want to help us out, tell them to get in touch with us on our forum, our discord, wherever, um because we would love that</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i mean we already do have several languages in the team, we speak english or german or<br>
<!-- -->persian or...</p>
<p><strong>Potassium:</strong><br>
<!-- -->australian</p>
<p><strong>Y_Less:</strong><br>
<!-- -->that's about it, yeah, australian, that's a unique language... yorkshire...</p>
<p><strong>Hual:</strong>
also we're pretty close with the turkish and romanian communities as well,<br>
<!-- -->they're pretty big</p>
<p><strong>Y_Less:</strong><br>
<!-- -->and i do have contacts in the russian community as well.</p>
<p><strong>Potassium:</strong><br>
<!-- -->so we are trying.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->it's tricky, it's hard, that's why it's not worked before.</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah and lack of effort. so the last kind of pre-loaded question from the forum today<br>
<!-- -->is: what are you most looking forward to about openmp? and i just thought this was<br>
<!-- -->really wholesome.</p>
<p><strong>everyone:</strong><br>
<!-- -->the release.</p>
<p><strong>Potassium:</strong><br>
<!-- -->after the release, just in general. it's a nice question because i'm glad that people can see that we're happy to be doing this and excited to be doing it. so yeah what are you looking forward to?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->just looking forward to getting to a state where either players are finally enjoying the<br>
<!-- -->features, or we get to a point where the rest of the community can take over, pretty much that to be honest</p>
<p><strong>Potassium:</strong><br>
<!-- -->anyone else want to add anything?</p>
<p><strong>j0sh...:</strong><br>
<!-- -->no bug reports</p>
<p><strong>Potassium:</strong><br>
<!-- -->i just i'm honestly just kind of looking forward to bringing together the community again<br>
<!-- -->because we all kind of separated and went off</p>
<p><strong>JustMichael:</strong><br>
<!-- -->it'd be nice to have a big increase of players, especially now that we talked<br>
<!-- -->about including the other communities that have gone their own ways, it'd be<br>
<!-- -->nice to have them then because yeah you know more players are better</p>
<p><strong>Potassium:</strong><br>
<!-- -->not even just player count, just in general, bringing the community back together</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah we're not doing this for the sake of a 15 year old game because the game is the greatest game ever, we're doing it because of the community</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah that's right</p>
<p><strong>Southclaws:</strong><br>
<!-- -->HOWEVER, it IS the greatest game ever!</p>
<p><strong>JustMichael:</strong><br>
<!-- -->can confirm!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->uhhhh vice city is better.</p>
<p><strong>Potassium:</strong><br>
<!-- -->liberty city is my home, i'll always love gta 3.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->so the team is completely split</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes. but on that note, we get a lot of questions asking like san andreas is such an old game, why are you bothering, why do you care, kind of thing. and i just want to answer<br>
<!-- -->that one, or start by answering that one, and say that i think it's important to remember that a large portion of the samp player base come from countries where technology isn't necessarily as up-to-date or as high priority as it is where some of us live, and a lot of our players play samp because it's one of the only games that can run on their pcs or that they can afford, so i don't know i just absolutely love the fact that we can give them the ability to play and create their own game modes like battle royales or racing modes or whatever,<br>
<!-- -->so that everyone can still experience these kind of games even though they can't afford like pubg or call of duty or you know, like they can't run those things</p>
<p><strong>Southclaws:</strong><br>
<!-- -->a side thing to add to that i think is the the scripting side of it, it's like a gateway drug in a way, it's a gateway for people to learn how to code, and if you learn how to code that can be great because you can make things and you can make games and you can have fun but you can also get a job doing it</p>
<p><strong>Potassium:</strong><br>
<!-- -->there are a LOT of people-</p>
<p><strong>Southclaws:</strong><br>
<!-- -->a lot of people here actually got jobs because of samp, i'm one of them. it's definitely a<br>
<!-- -->great gateway to learning how to code because pawn is quite a simple language, and then you might move into C++ to build plugins and that's kind of a more complex language, and then you might move to doing web stuff like php and javascript because of user<br>
<!-- -->control panels and forums and stuff, and it just goes out from there and that's one of the main things i love about it, i don't really play the game anymore and i haven't really written much code for a few years, but i just love the community, i love helping people with that side of things, so that's why i'm in it</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i think you can track the history of games over the last 15 years through samp modes.<br>
<!-- -->whatever the current popular games is, there's a samp version of it</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah absolutely, and i love that!</p>
<p><strong>Y_Less:</strong><br>
<!-- -->pubg - samp. battle royale - samp. microsoft flight simulator samp.</p>
<p><strong>iAmir:</strong>
among us...</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i've always wanted to write a Trouble in Terrorist Town style game mode... maybe that's our next stream, making a TTT gamemode.</p>
<p><strong>Potassium:</strong><br>
<!-- -->but yeah just back on that note, i don't think there are many games or communities where you can do that kind of thing, where you can have different modes, maybe roblox...</p>
<p><strong>Southclaws:</strong><br>
<!-- -->garry's mod is like the closest thing, and even that you need a semi-modern pc to actually run it, and when you join the server you usually download 500 megabytes of anime skins</p>
<p><strong>Potassium:</strong><br>
<!-- -->every time i play garry's mod i get texture errors and stuff, and i have a good pc. so anyway i think we will go ahead and take some live questions from chat, so you guys listening...</p>
<p><strong>Y_Less:</strong><br>
<!-- -->just quickly before you do that, one other thing related to that point we were saying lots of people have got started in samp learning to code through pawn, it's quite a simple<br>
<!-- -->language, and a lot of people always ask why we are using pawn when it's such a simple<br>
<!-- -->language... and that is the answer, we use it because it's a simple language, anybody can pick it up. it's an 18+ game but let's face it we have a lot of kids playing, they come along and go okay i want to make my own server how do i do that? well first you need to download this editor and these plugins, and then you download this other compiler and these other things and do this and this and this, and then this and then this and this, and<br>
<!-- -->then you can start writing your first code in this horribly conflicted language. they just go<br>
<!-- -->oh... whereas with samp it was how do i start coding? open this, done.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->and you've already got a piece of code to start with as well.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->the barrier to entry is zero</p>
<p><strong>Potassium:</strong><br>
<!-- -->put it this way, if i can do it anyone can do it. and that is not an exaggeration!</p>
<p><strong>Southclaws:</strong><br>
<!-- -->Potassium learns to code - the video series. when's that happening?</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes, i'm so down for that! but you guys are going to get very angry.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->i actually think that would be a realy good series.</p>
<p><strong>Potassium:</strong><br>
<!-- -->i'm very hard to teach, and also i will cry. but that's okay, that's good content i guess! anyway we're gonna take some live questions from chat, so if you guys in the chat have any questions, which i know you do...</p>
<p><strong>JustMichael:</strong><br>
<!-- -->someone just asked about GetAsyncKeyState</p>
<p><strong>iAmir:</strong>
i'm not sure actually having that is actually a good idea because what samp actually does right now is listening to key events, so what player has mapped it to the gta game itself, so for example when you press F, if you change the F button to i don't know G for example, for interim vehicles when they press G, it's gonna get called on the server side, so what they want and what they were asking is actually sending all the keys, all the key events to the server, which is actually not um a good idea because you can actually run a key logger or stuff like that, and you're gonna have some security issues</p>
<p><strong>Southclaws:</strong><br>
<!-- -->it also proves the key layout is then controlled by the server and not the player, and that's kind of weird because if you like using a different keyboard layout, like maybe you like using ESDF which i know some fps players actually use things like that and other layouts for WASD, if you join a server and suddenly all your buttons are kind of different then<br>
<!-- -->it can be kind of confusing. so i mean we could add more keys that can be rebound, but<br>
<!-- -->i think using the games keys actually gives players the ability to customize their sort of<br>
<!-- -->layout and stuff to match them, not the server forcing them to press F if they want to use E for entering cars or something, picking up items, stuff like that</p>
<p><strong>iAmir:</strong>
i think how we should handle it is add some actions not keys just a bunch of actions so anyone can bind anything to them</p>
<p><strong>Southclaws:</strong><br>
<!-- -->we have Y and N as well that were added at some point, was it H? i can't remember, there were some new keys added at one point. we could do stuff like that, there was a there was actually a key i use... tab is actually a key action, but it's also the scoreboard, so users can't really use it, but if you rebind tab to like something like R, suddenly you've got a new key to<br>
<!-- -->actually rebind on the server side. so there's there's potential there.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->yeah a better way is just to have the server define actions and then the client can get that<br>
<!-- -->list of actions and just assign their own keys but then still it's just they've triggered this action they've pressed this key.</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah and also not allow people to bind every single key on the keyboard and then keylog people.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->it won't work because they if they're allowed to bind their own keys they can change it so the keylogger is useless, but they've triggered these actions in this order, what key is that?i don't know</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i'm not sure if this is a direct question to us but it just says what is the recommended amount of dedicated rams</p>
<p><em>everyone laughs</em></p>
<p><strong>Potassium:</strong><br>
<!-- -->that's jamie</p>
<p><strong>JustMichael:</strong><br>
<!-- -->bloody troll</p>
<p><strong>Southclaws:</strong><br>
<!-- -->get trolled bro</p>
<p><strong>iAmir:</strong><br>
<!-- -->so i've listed some questions, one of them was about ddos and people attacking other servers which is very common in the spanish community</p>
<p><strong>Potassium:</strong><br>
<!-- -->all communities</p>
<p><strong>iAmir:</strong><br>
<!-- -->yeah, kind of all communities, but in the spanish community there's some guy, stuff like that</p>
<p><strong>Southclaws:</strong><br>
<!-- -->oh yeah Graber had to write a weird proxy thing</p>
<p><strong>iAmir:</strong><br>
<!-- -->yyeah and people are now asking about that, for ddos protection</p>
<p><strong>JustMichael:</strong><br>
<!-- -->there's nothing we can do about ddos itself</p>
<p><strong>Southclaws:</strong><br>
<!-- -->the thing that Graber wrote and, something that i've worked on, and actually you've<br>
<!-- -->worked on this michael, is a proxy, which is kind of awkward to get working because<br>
<!-- -->of how samp quote unquote encrypts data, it uses the ports like a very simple cipher but if you can put a proxy on another server and then use round robin dns or something then that can be a good mitigation technique, so i think providing the tools to do that would be a good thing</p>
<p><strong>JustMichael:</strong><br>
<!-- -->there would be a problem though if someone was to ddos the actual load balance or proxy itself then that would ruin it for all servers</p>
<p><strong>Southclaws:</strong><br>
<!-- -->yeah but a proxy load balancer is a lot lighter than the game server so you can dedicate multiple threads to actually handle that load, it's kind of how cloudflare and all those proxy services work so you know if you're a big server and you've got the budget then you can<br>
<!-- -->you know rent a bunch of vps's, roundup and dns and put proxies on all of them, and then that kind of takes the load and then your actual real server you can just hide the ip address a bit and no one can ddos it directly</p>
<p><strong>iAmir:</strong><br>
<!-- -->the results of our discussion is if they are actually targeting the server itself not the openmp server for example like the machine itself, if they are targeting that with<br>
<!-- -->a stressor or some kind of exploits, stuff like that, you cannot actually do anything about it. we can fix our job but we can't fix details because that's just how the internet works. if those are exploits or stressor or some kind of ddos tools, stuff like that, if they are<br>
<!-- -->actually targeting openmp server we can find the issue and fix it as soon as possible that<br>
<!-- -->we figure it out, but about the server itself, the machine, there's actually no way we can handle that because there's nothing for us to fix, so that's actually other people's work buying ddos protection, having good servers, paying more</p>
<p><strong>JustMichael:</strong><br>
<!-- -->that comes with anyone running any kind of application in production, any kind of server, that's not a specific issue to us</p>
<p><strong>iAmir:</strong><br>
<!-- -->yeah even just a simple website, people can target a website for that to take down the servers</p>
<p><strong>Southclaws:</strong><br>
<!-- -->they can target your home router</p>
<p><strong>Y_Less:</strong><br>
<!-- -->you just can't stop ddos in software, it's just not possible, they keep saying how can we stop ddos, buy ddos protection, that's it.</p>
<p><strong>Hual:</strong><br>
<!-- -->basically we can stop it if it's abusing an openmp exploit, otherwise nothing we can do.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->it would also be good if we had the community report these to make sure they actually report these issues immediately when they find them because that would just help us<br>
<!-- -->to fix them if something's gonna be on</p>
<p><strong>iAmir:</strong><br>
<!-- -->yeah one of the biggest issues that we had in samp was people couldn't report bugs, there was like some thread or discussions stuff like that and people were reporting bugs or adding suggestions and those messages were get lost in a day.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->i remember there was a bug thread that got deleted like three hours after it was created when it had i think it was like 27 or 30 different replies in it, but all bugs, and it was just gone</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i found a bug where you could read logs from remotely and no one cared about it and i got no reply</p>
<p><strong>Potassium:</strong><br>
<!-- -->i don't understand this question but Southclaws: sent it to me so it says: samp doesn't support ip failover/alias - will openmp support it?</p>
<p><strong>Southclaws:</strong><br>
<!-- -->the reason the reason samp doesn't support that is because it uses the actual port and the address to encrypt its packets, but you can just not do that when the client is out. while we've got to use the samp server we'll be kind of bound to the weird encryption that exists, but after that we can do like a regular udp proxy type thing. and yeah you can do failover<br>
<!-- -->for dns as well.</p>
<p><strong>iAmir:</strong><br>
<!-- -->uh there's also another question that i have in my list that people ask in chat, someone's asked more like a suggestion, can we consider giving servers the ability to add their favicon that is shown on the client next to the server title for example in launcher. we could we can actually do that right now with having even some client or some launcher i mean<br>
<!-- -->yeah with a custom launcher we can actually add a custom rule to the query so we read that in our own launcher</p>
<p><strong>Southclaws:</strong><br>
<!-- -->there's servers.net which i wrote three years ago or two years ago or something, i can't remember, i think that actually had the support for a field called "banner" which was meant to be an image that would like be like a graphic you could put in the background of your server page or the server list or something</p>
<p><strong>JustMichael:</strong><br>
<!-- -->there is also the fact that now that we've got the indexer you've added login support for users so they could easily even without it being on the server they could technically just log into that and put it on the index and then yeah all the launchers could just go off the indexer</p>
<p><strong>Southclaws:</strong><br>
<!-- -->the the plan with the indexer is to basically launch a server and you log into the indexer and the indexer will give you a token like an api token and you put that token into your server config file and now the indexer has verified that you own that server, so then on the indexer's web interface you can go and edit the description, the icon, the image, whatever whatever we end up adding, gifs, i don't know. then you don't have to modify a config file that is on a vps, log in and upload ssh, whatever, you just go to a website and you can just edit it with your browser and it's a lot simpler.</p>
<p><strong>Potassium:</strong><br>
<!-- -->alright before we end for today, people keep asking us to show videos of the progress. so<br>
<!-- -->we don't have that, we don't have videos because there's not really anything to show at<br>
<!-- -->the moment, right?</p>
<p><strong>JustMichael:</strong><br>
<!-- -->we have been live streaming recently and showing openmp progress</p>
<p><strong>iAmir:</strong><br>
<!-- -->there's actually nothing to show on a stream or as a video because it's just a simple server application which is like a console</p>
<p><strong>Hual:</strong><br>
<!-- -->development is occasionally streamed on discord</p>
<p><strong>Potassium:</strong><br>
<!-- -->so if you guys join our discord server Southclaws: and other people do often stream their development and stuff, their progress, in discord, so you just kind of join the discord channel and you watch the stream and you can just join the talk as well and chat and ask questions. we are quite open with it and do a lot of public stuff that you guys can join.</p>
<p><strong>JustMichael:</strong><br>
<!-- -->someone just asked about custom ui servers using htmlcs and js. and we have<br>
<!-- -->talked about this a lot and CEF will not be part of it.<br>
<!-- -->um google adsense um sources of<br>
<!-- -->nonsense on your screen yeah also good<br>
<!-- -->looking<br>
<!-- -->so you have to work on xp oh yeah yeah<br>
<!-- -->yeah also cef isn't small<br>
<!-- -->yeah keyboard yeah<br>
<!-- -->there's gonna be a problem with people<br>
<!-- -->who have low end computers<br>
<!-- -->people who have like weak computers to<br>
<!-- -->play<br>
<!-- -->that game so if you want to<br>
<!-- -->know you can just play mta<br>
<!-- -->it's fine like we want judge<br>
<!-- -->i mean eventually i guess we're gonna<br>
<!-- -->have um client-side<br>
<!-- -->c api too right so if we actually add<br>
<!-- -->that<br>
<!-- -->and having that yeah josh i mean<br>
<!-- -->we haven't talked about it yes but<br>
<!-- -->actually having that is actually a good<br>
<!-- -->idea because<br>
<!-- -->uh people can add voice chat by<br>
<!-- -->themselves by interacting<br>
<!-- -->our own api and um<br>
<!-- -->for cef stuff like that they can edit<br>
<!-- -->themselves<br>
<!-- -->if we add c api<br>
<!-- -->so yeah it's probably uh possible<br>
<!-- -->for later users<br>
<!-- -->well we probably won't ever have cef<br>
<!-- -->yeah we're not going to have that built<br>
<!-- -->in not officially<br>
<!-- -->someone else could edit it unofficially<br>
<!-- -->yeah<br>
<!-- -->yeah but i'm not sure we will accept it<br>
<!-- -->in the<br>
<!-- -->registry of official plugins also so<br>
<!-- -->i don't know yeah there are things<br>
<!-- -->someone asked if we have a official map and model editor
uh yeah we have a mirror working a model<br>
<!-- -->viewer<br>
<!-- -->uh not sure<br>
<!-- -->yeah cool<br>
<!-- -->all right uh and we've not really<br>
<!-- -->discussed it so<br>
<!-- -->we could say oh we would like one which<br>
<!-- -->is true but there's no plans to make one<br>
<!-- -->because there are ones already and they<br>
<!-- -->work and they're fine and everyone<br>
<!-- -->knows them</p>
<p><strong>Potassium:</strong><br>
<!-- -->I think we will end it there because i think we answered a lot of questions, but you know if you have more questions please go to our forum or our discord and ask there, because we do want to answer them.</p>
<p><strong>Y_Less:</strong><br>
<!-- -->some people are concerned about not being not native speakers and not understanding what we've talked about so we'll try and write it up</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah i'll try and get a transcript up and then our awesome contacts in other communities can translate for us, that would be great</p>
<p><strong>BigETI:</strong><br>
<!-- -->i mean if you upload it on youtube that should be fairly easy</p>
<p><strong>Potassium:</strong><br>
<!-- -->yeah that's the plan, we're gonna put this on youtube, and i'm gonna try to put it on some<br>
<!-- -->kind of podcast platform too so people can listen to it</p>
<p><strong>Southclaws:</strong><br>
<!-- -->i'm sure youtube will generate some very hilarious captions as well</p>
<p><strong>Potassium:</strong><br>
<!-- -->so like we said we do intend to stream regularly from now on, not just q&amp;a sessions but we<br>
<!-- -->would like to stream development progress, i think we talked about doing some community games like stuff like among us and other games that we could all play together, so make sure you follow this channel, join our discord, subscribe on youtube, follow our twitter,<br>
<!-- -->facebook, instagram, sign up to our forum, all that good stuff, everything is linked</p>
<p><strong>iAmir:</strong><br>
<!-- -->you forgot vk</p>
<p><strong>Potassium:</strong><br>
<!-- -->yes vk</p>
<p><strong>Southclaws:</strong><br>
<!-- -->there's a reddit as well</p>
<p><strong>Potassium:</strong><br>
<!-- -->everything should be linked below, otherwise we do have a linktree, it's linktr.ee/openmultiplayer i believe, everything is linked on that, but yeah i guess thank you guys for your time, thank you to all the viewers for watching, or listening rather, the link tree link is in the twitch chat right now, uh one more question quickly, are there plans to open a patreon for people wanting to support the project?</p>
<p><strong>everyone:</strong><br>
<!-- -->we haven't really discussed anything like that<br>
<!-- -->donations are always good but we don't really need them right now<br>
<!-- -->yeah at the moment we don't need them<br>
<!-- -->i think yeah i mean stuff like the server costs and whatever it would be nice<br>
<!-- -->they're fairly cheap<br>
<!-- -->the indexer probably costs like five dollars a month it's like nothing<br>
<!-- -->yeah yeah and the websites are all hosted for free<br>
<!-- -->yeah maybe maybe in the future we'll open up some kind of way that you guys can<br>
<!-- -->support the project if you want to, but you know we're not we're not doing it to make money so that's something we'll discuss<br>
<!-- -->also it's kind of like you're committing even more and i don't think we can just do that<br>
<!-- -->because we all work for a living</p>
<p><strong>Potassium:</strong><br>
<!-- -->alright well thank you guys so much for being here and for answering all these questions,<br>
<!-- -->and thank you twitch chat for being here and for following and everything, we'll see you on discord</p>
<p><strong>everyone:</strong><br>
<!-- -->thank you for hosting us</p>
<p><strong>Potassium:</strong><br>
<!-- -->you're welcome, see you guys!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[open.mp API 设计]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/scripting-api</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/scripting-api</guid>
            <pubDate>Tue, 14 Apr 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[open.mp 的一个核心关注点是保持向后兼容性——你现有的 SAMP 问题，以及 open.mp 如何提升开发体验。]]></description>
            <content:encoded><![CDATA[<p>open.mp 的一个核心关注点是保持<strong>向后兼容性</strong>——你现有的 SA<!-- -->:MP<!-- --> 脚本可以开箱即用。然而，open.mp 也引入了改进，以修复不一致之处，并使脚本编写更直观、更强大。下面我们来看看一些我们正在解决的常见 SA<!-- -->:MP<!-- --> 问题，以及 open.mp 如何提升开发体验。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>以下内容已过时，不反映 open.mp 的当前状态。本文发布于此仅作归档用。</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="介绍">介绍<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E4%BB%8B%E7%BB%8D" class="hash-link" aria-label="介绍的直接链接" title="介绍的直接链接" translate="no">​</a></h2>
<p>首先，一个<strong>极其重要</strong>的澄清——现有的脚本仍然可以<strong>原样运行</strong>。我们在向后兼容性方面投入了大量精力，并在每个决策中都将其铭记于心。出于此原因，许多我们想要的改进都无法实现，而其他一些代码也因兼容性要求而变得极为复杂。</p>
<p>尽管如此，我们仍可在各处进行改进。让我们来看看 SA<!-- -->:MP<!-- --> 脚本中存在的一些不一致性示例：</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="标签">标签<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%A0%87%E7%AD%BE" class="hash-link" aria-label="标签的直接链接" title="标签的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><code>Menu:CreateMenu</code> - 有标签。</li>
<li class=""><code>DB:db_open</code> - 有标签。</li>
<li class=""><code>CreateVehicle</code> - 无标签。</li>
<li class=""><code>CreateActor</code> - 无标签。</li>
</ul>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name" style="color:#36acaa">SELECT_OBJECT_GLOBAL_OBJECT</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property expression number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name" style="color:#36acaa">SELECT_OBJECT_PLAYER_OBJECT</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property expression number" style="color:#36acaa">2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">forward </span><span class="token function" style="color:#d73a49">OnPlayerSelectObject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> type</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> modelid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">fX</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">fY</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">fZ</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p><code>type</code> 是无标签的，所有 SA<!-- -->:MP<!-- --> 定义的常量都是如此；这与 pawn 的默认常量不同：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">native File</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">fopen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filemode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">mode </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> io_readwrite</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="命名">命名<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E5%91%BD%E5%90%8D" class="hash-link" aria-label="命名的直接链接" title="命名的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><code>SetVehiclePos</code> - "Vehicle" 在函数名中间。</li>
<li class=""><code>TextDrawTextSize</code> - "TextDraw" 在开头。</li>
<li class=""><code>db_open</code> - "db" 在开头，且是小写。</li>
<li class=""><code>fread</code> - "file" 在开头，且是缩写形式。</li>
<li class=""><code>asin</code> - SA<!-- -->:MP<!-- --> 新增的函数，没有使用驼峰命名法。</li>
</ul>
<p>不一致性：</p>
<ul>
<li class="">GetVehicleZAngle - "Z-Angle"</li>
<li class="">GetVehicleRotationQuat - "Rotation"</li>
<li class="">SetPlayerFacingAngle - "Facing Angle"</li>
<li class="">SetObjectRot - "Rot"</li>
</ul>
<p>尽管如此，大多数库现在已统一采用 <code>模块_方法</code> 的命名约定。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="常量">常量<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E5%B8%B8%E9%87%8F" class="hash-link" aria-label="常量的直接链接" title="常量的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><code>65535</code> 无效玩家、演员、文本绘图等的值。它也是无效车辆的值，但 <code>0</code> 有时也会作为无效车辆 ID 返回。</li>
<li class=""><code>0</code> 无效文件的值，有时是车辆（同时也是 <code>65535</code>）。也是许多缺失事物的值，如动作状态和武器。</li>
<li class=""><code>255</code> 无效队伍和菜单的值。</li>
<li class=""><code>-1</code> 无效帮派区域和武器状态的值。</li>
</ul>
<p>此外，许多库使用 <code>0x80000000</code> 和 <code>-1</code> 表示无效状态，因为它们成为有效 ID 的可能性要小得多。65535 是一个相当大的数字，但一个大型服务器很容易拥有比这更多的物体。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="针对玩家的函数">针对玩家的函数<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E9%92%88%E5%AF%B9%E7%8E%A9%E5%AE%B6%E7%9A%84%E5%87%BD%E6%95%B0" class="hash-link" aria-label="针对玩家的函数的直接链接" title="针对玩家的函数的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><code>CreateObject</code> 和 <code>CreatePlayerObject</code> 有全局和针对玩家的版本。</li>
<li class=""><code>SetPlayerMapIcon</code> 没有全局版本。</li>
<li class=""><code>SetGravity</code> 没有针对玩家的版本，尽管这可能是最常被要求的针对玩家功能之一，并且 YSF 和其他插件几乎立即添加了它。</li>
<li class=""><code>CreateVehicle</code> 没有针对玩家的版本，尽管也一直被反复要求。但也没有任何（公开的）插件添加此功能，甚至streamer插件也没有。</li>
<li class=""><code>SendClientMessage</code> 和 <code>SendClientMessageToAll</code> 有全局和针对玩家的版本，但与大多数其他函数不同，针对玩家的版本是默认的。</li>
<li class=""><code>GangZoneShowForPlayer</code> 和 <code>GangZoneShowForAll</code> 菜单、帮派区域和文本绘图是 SA<!-- -->:MP<!-- --> 默认函数中<strong>唯一</strong>可以指定哪些玩家可以看到它们的。所有其他的都是要么所有人可见，要么仅限一人。</li>
</ul>
<p>当然，库和插件后来极大地扩展了此模型，现在大多数优秀的插件都允许对任何给定实体的可见玩家子集（组）进行非常精细的控制。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ids">IDs<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#ids" class="hash-link" aria-label="IDs的直接链接" title="IDs的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><code>CreateObject</code> 和 <code>CreatePlayerObject</code> 这些函数的 ID 池是共享的。如果全局物体的 ID 是 <code>4</code>，则任何玩家物体都不能拥有 ID <code>4</code>，但多个玩家可以拥有不同的物体，且这些物体都可以拥有 ID <code>5</code>。</li>
<li class=""><code>Create3DTextLabel</code> 和 <code>CreatePlayer3DTextLabel</code> ID 池是分开的——前 <code>1024</code> 个 ID 是全局的，后 <code>1024</code> 个是针对玩家的。每个玩家最多可以有 <code>2048</code> 个 3D 文本，但每种类型只有 <code>1024</code> 个，尽管在客户端这没有区别。</li>
<li class=""><code>SetPlayerMapIcon</code> ID 是手动指定的，最多 32 个。有一段时间，客户端并未检查此限制，导致了潜在的 ACE 漏洞。</li>
<li class=""><code>ShowPlayerDialog</code> ID 是手动指定的，没有限制。ID 也完全没有意义，因为一个玩家一次只能看到一个对话框。</li>
<li class=""><code>SetTimer</code> ID 会回绕，且不检查是否存在具有相同 ID 的定时器。你需要启动超过 40 亿个定时器才可能遇到这个问题，但这是可能发生的——它们甚至不必都保持运行。</li>
</ul>
<p>当然，有些人依赖 ID 按照非常特定的顺序分配，然后当他们添加或移除一辆车辆时，就会疑惑为什么整个游戏模式会崩溃。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="兼容性">兼容性<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E5%85%BC%E5%AE%B9%E6%80%A7" class="hash-link" aria-label="兼容性的直接链接" title="兼容性的直接链接" translate="no">​</a></h2>
<p>所以，再次强调，我们必须非常明确地指出，所有现有的 <em>"SA<!-- -->:MP<!-- --> 代码"</em> 都将有效。这到底是什么意思？</p>
<p>任何满足以下条件的代码：</p>
<ul>
<li class="">用 Pawn 编写。</li>
<li class="">使用原始的 SA<!-- -->:MP<!-- --> API，没有插件。</li>
<li class="">用我们的头文件重新编译。</li>
<li class="">已经使用社区编译器。</li>
</ul>
<p>都将有效。</p>
<p>但是：</p>
<ul>
<li class="">如果你使用插件用非 Pawn 语言编写代码，该插件可能首先需要移植。所以你的代码不会立即生效。</li>
<li class="">如果你使用其他插件，如streamer、YSF、audio等；它们可能已经有效，可能需要移植，或者可能完全多余，因为其功能已集成到核心服务器中。所以你的代码<strong>可能</strong>有效。</li>
<li class="">如果你只有游戏模式的 .AMX 文件，而没有原始源代码，为什么？无论如何，虽然所有 SA<!-- -->:MP<!-- --> 函数都存在，但有些函数已被 Pawn 代码或宏重做或替换，你<strong>必须</strong>重新编译。所以如果你不能，你的代码将完全无效。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="构建">构建<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%9E%84%E5%BB%BA" class="hash-link" aria-label="构建的直接链接" title="构建的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="示例">示例<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="示例的直接链接" title="示例的直接链接" translate="no">​</a></h3>
<p>让我们从一个极其简单的 SA<!-- -->:MP<!-- --> 游戏模式开始。</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">include</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property string" style="color:#e3116c">&lt;a_samp&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">public </span><span class="token function" style="color:#d73a49">OnGameModeInit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SetGameModeText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Example Script"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">AddPlayerClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">public </span><span class="token function" style="color:#d73a49">OnPlayerSpawn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">public </span><span class="token function" style="color:#d73a49">OnPlayerEnterCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SendClientMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0xFF0000AA</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"You won!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>你出生，前往检查点，然后获胜。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="转换">转换<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E8%BD%AC%E6%8D%A2" class="hash-link" aria-label="转换的直接链接" title="转换的直接链接" translate="no">​</a></h3>
<p>要为 open.mp 构建此脚本，我们需要更改第一个包含文件并添加一个定义。</p>
<p>这：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">include</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property string" style="color:#e3116c">&lt;a_samp&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>变成：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name" style="color:#36acaa">OPENMP_COMPAT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">include</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property string" style="color:#e3116c">&lt;openmp\openmp&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>你可能遇到的第一个错误是：<code>open.mp scripts require the community compiler from: git.io/pawn-compiler</code></p>
<p>如果你遇到此错误，请前往 <a href="https://git.io/pawn-compiler" target="_blank" rel="noopener noreferrer" class="">https://git.io/pawn-compiler</a> 并下载编译器版本 3.10.10 或更高版本。对于正式发布版本，我们希望有一个集成了此编译器的 pawno 等效工具，但尚未完成。</p>
<p>我<strong>强烈建议</strong>首先尝试用此编译器编译你的游戏模式，因为它重新启用了常量正确性警告，所以你可能会立即看到大量新警告（这<strong>不是</strong>编译器的问题，这些是你代码中始终存在但之前被忽略的问题）。</p>
<p>你可能还想将这些头文件替换为：</p>
<p><a href="https://github.com/pawn-lang/pawn-stdlib" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/pawn-stdlib</a><br>
<a href="https://github.com/pawn-lang/samp-stdlib" target="_blank" rel="noopener noreferrer" class="">https://github.com/pawn-lang/samp-stdlib</a></p>
<p>即使不使用 open.mp，这样做也是一件好事，因为它们修复了原始头文件中的大量标签和常量问题。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="警告">警告<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E8%AD%A6%E5%91%8A" class="hash-link" aria-label="警告的直接链接" title="警告的直接链接" translate="no">​</a></h3>
<p>如果你在使用新编译器和新版本 <code>a_samp</code> 时没有收到任何警告，现在你会看到一系列新警告，内容类似：</p>
<p><code>warning 234: function is deprecated (symbol "AddPlayerClass") Use "Class_Add" instead.</code></p>
<p>你有三个选项 - 它们都受支持：</p>
<ul>
<li class=""><strong>忽略警告：</strong> 代码仍然有效。</li>
<li class=""><strong>抑制警告：</strong> 将 <code>OPENMP_COMPAT</code> 更改为 <code>OPENMP_QUIET</code>：</li>
</ul>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name" style="color:#36acaa">OPENMP_QUIET</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">include</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property string" style="color:#e3116c">&lt;openmp\openmp&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<ul>
<li class=""><strong>修复警告：</strong> 有些函数已更改名称以保持一致性；有些函数已更改参数，因为旧函数已演变且未完全暴露 open.mp 的功能。目前还没有简单的方法来转换每个函数，但你可以在慢慢转换代码时保持警告开启 - 旧函数将继续完美运行。</li>
</ul>
<p>转换分为三个阶段：</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="define-openmp_quiet"><code>#define OPENMP_QUIET</code><a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#define-openmp_quiet" class="hash-link" aria-label="define-openmp_quiet的直接链接" title="define-openmp_quiet的直接链接" translate="no">​</a></h3>
<p>使用此定义允许你的游戏模式编译时不会因已弃用的函数而产生新警告。但你不应坚持使用此定义，并且隐式转换仅适用于 Pawn 代码。你可以在这种模式下转换代码，因为新 API 也有效，但你无法使用编译器查看哪些地方仍有问题。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="define-openmp_compat"><code>#define OPENMP_COMPAT</code><a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#define-openmp_compat" class="hash-link" aria-label="define-openmp_compat的直接链接" title="define-openmp_compat的直接链接" translate="no">​</a></h3>
<p>这是第二阶段。一旦你想要开始利用 open.mp 的所有改进功能，例如精细的针对玩家实体控制和移除限制，你就需要开始使用函数的新版本。新函数始终可用，但你可能不知道哪些地方需要转换。这将对旧函数给出警告，但它们仍然有效，允许你一次转换部分游戏模式。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="无定义">无定义<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%97%A0%E5%AE%9A%E4%B9%89" class="hash-link" aria-label="无定义的直接链接" title="无定义的直接链接" translate="no">​</a></h3>
<p>一旦你认为已完成了代码转换，可以移除定义：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">include</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property string" style="color:#e3116c">&lt;openmp\openmp&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>现在，对于仍在使用的任何旧代码，你将收到错误而非警告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新-api">新 API<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%96%B0-api" class="hash-link" aria-label="新 API的直接链接" title="新 API的直接链接" translate="no">​</a></h2>
<p>现在我们已经看到了旧 API 的问题，以及如何找到需要应用新 API 的地方，我们应该实际看看新 API 是如何解决先前提到的问题的：</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="标签-1">标签<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%A0%87%E7%AD%BE-1" class="hash-link" aria-label="标签的直接链接" title="标签的直接链接" translate="no">​</a></h3>
<p>现在函数几乎在所有地方都使用标签。我们试图在过多的标签警告和不足的有用信息之间找到平衡，但警告是有原因的，可以帮助发现你可能遗漏的问题。例如，将车辆作为参数传递给物体函数，或给予某人一个不存在的武器：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 此代码没有警告，尽管它显然是错误的。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">new object </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">CreateObject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">various</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> here</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">PutPlayerInVehicle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 这里也一样 - 没有 20 号武器，尽管它在有效武器 ID 中。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">GivePlayerWeapon</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>如果所有明显错误的代码都能给出警告，那会好得多。这是类型安全语言的力量，虽然 Pawn 不是完全类型安全的，但我们可以通过标签来接近这一点。这些例子变成了：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// warning 213: 标签不匹配：应为标签 "Vehicle"，但找到 "Object"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">new Object</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">object </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Object@</span><span class="token function" style="color:#d73a49">Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">various</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> here</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Player_PutInVehicle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// warning 213: 标签不匹配：应为标签 "WeaponType"，但找到但找到无标签 ("_")</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">GivePlayerWeapon</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 这个不会给出警告：</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">GivePlayerWeapon</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WEAPON_COLT45</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="命名-1">命名<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E5%91%BD%E5%90%8D-1" class="hash-link" aria-label="命名的直接链接" title="命名的直接链接" translate="no">​</a></h3>
<p>大多数新函数使用许多库和插件已经采用的命名方案的改进版本 - <code>模块_动词名词</code>。有些没有，当它们是独立的、不适用于任何更大模块时，但在大多数情况下，你可能能猜到所需函数的名称。</p>
<p>不再需要纠结某个元素是 "Rot" 还是 "Rotation"，除非函数名过长（32+ 个字符，编译器不接受），否则没有缩写。</p>
<p>想要更改物体的模型？<code>Object_SetModel</code>。想要向玩家显示文本？<code>Text_Show</code>。</p>
<p>动词的数量是有限的 - <code>Get</code>、<code>Set</code>、<code>Create</code>、<code>Destroy</code>、<code>Add</code>、<code>Remove</code>、<code>Show</code>、<code>Hide</code>、<code>Run</code>、<code>Move</code>、<code>Stop</code> 和 <code>Count</code>。可能会添加更多，并可能出现在特殊情况下，但通常如果其中之一适用，那很可能就是它。</p>
<p>到目前为止，最常见的是 <code>Get</code> 和 <code>Set</code>，与 SA<!-- -->:MP<!-- --> 不同，它们现在总是成对出现 - 如果你可以设置任何参数，你以后也可以获取它。它们也是最常与名词搭配的动词 - 你需要指定获取或设置什么 - <code>Health</code>、<code>Position</code>、<code>Model</code>、<code>Width</code> 等。</p>
<p>一些例子：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Menu_SetDisabled</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Menu</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">menuid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> bool</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">disabled</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Menu_GetDisabled</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Menu</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">menuid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Text_SetAlignment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> alignment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Text_GetAlignment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Object_Move</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Object</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">posX</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">posY</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">posZ</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">speed</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">rotX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FLOAT_NAN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">rotY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FLOAT_NAN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">rotZ </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FLOAT_NAN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">DBResult_CountRows</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">DBResult</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">dbresult</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Player_Spawn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>请注意，模块和标签名称总是匹配的 - <code>Vehicle</code>、<code>DB</code>、<code>Player</code> 等。<a href="https://github.com/pawn-lang/compiler/issues/234" target="_blank" rel="noopener noreferrer" class="">这除了保持一致性外还有其他原因</a> - 它提供了更面向对象（OO）的接口，并且更容易记忆。</p>
<p>然而，你可能在前面的例子中注意到函数 <code>Object@Create</code>，而不是 <code>Object_Create</code>。原因是第一个参数的内容。在上面七个例子中，第一个参数都是被操作的实体（物体、车辆、玩家等）。你想获取特定实体的位置。你想移动特定实体。你想获取特定实体的剩余时间。这再次映射到类似 OO 的 API - <code>Player_Spawn(playerid)</code> 可以看作 <code>player.Spawn()</code>。PAWN 不能这样做，但这并不意味着集成到此 API 的其他语言不能。用 C++ 术语来说 - <code>_</code> 是 <code>.</code> 或 <code>-&gt;</code>，并且始终需要将有效的 ID 作为第一个参数。</p>
<p>但是，函数 <code>Dialog_IsValid(Dialog:id)</code> 根据定义，其第一个参数可能不是有效 ID（否则它的意义何在<sup><a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#user-content-fn-1-b0e7ce" id="user-content-fnref-1-b0e7ce" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">1</a></sup>？），而 <code>Icon_Create(image, Float:x, Float:y, Float:z)</code> 根本不接收 ID。因此，它们变成了 <code>@</code> 替代 - 在 C++ 语法中是 <code>::</code>。它们可能根本不接收 ID，并且绝对不需要有效的 ID（<code>@Destroy</code> 也属于这类函数，因为销毁实体是逻辑上对实体外部的操作，而不是对实体本身的操作）。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="常量-1">常量<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E5%B8%B8%E9%87%8F-1" class="hash-link" aria-label="常量的直接链接" title="常量的直接链接" translate="no">​</a></h3>
<p>首先，我们尽可能使用 <code>const</code> 和 <code>enum</code> 而不是 <code>#define</code> 来定义所有东西，除非我们期望它们被覆盖（如 <code>MAX_PLAYERS</code>）：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">enum</span><span class="token plain"> </span><span class="token class-name">ObjectMaterialTextAlignment</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MATERIAL_TEXT_ALIGN_LEFT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MATERIAL_TEXT_ALIGN_CENTRE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MATERIAL_TEXT_ALIGN_RIGHT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p><code>Object_SetMaterialText</code> 现在将只接受这三个值之一，不接受其他值。</p>
<p>那无效 ID 呢？我们也把它们统一了。所有实体现在都使用相同的无效值，这个值远在可能有效值的范围之外 - open.mp 移除了几乎所有限制，所以像 <code>65536</code> 这样的无效值就行不通了。</p>
<p>这个新的无效值是什么？我们还没有决定... 有两个主要竞争者，各有优缺点，这个决定并不像乍看起来那么容易。但幸运的是，它对内部工作影响不大，因为我们几乎可以立即切换。</p>
<p>这两个选择解释如下，如果你能提供反馈，我们将不胜感激：</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="0"><code>0</code><a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#0" class="hash-link" aria-label="0的直接链接" title="0的直接链接" translate="no">​</a></h4>
<p>使用 <code>0</code> 作为无效值有一些优点：</p>
<ul>
<li class="">它不是无效索引，所以当返回且未正确检查时，你的代码不会崩溃。它可能无法完美工作，但至少能继续执行某些操作。</li>
<li class="">检查起来非常容易，意图显而易见：<!-- -->
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">new Object</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">object </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Object@</span><span class="token function" style="color:#d73a49">Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">various</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> here</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Object_SetMaterialText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">object</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Couldn't create the object."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
</li>
<li class="">新声明的变量默认是无效值：<!-- -->
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">new Dialog</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">d</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<!-- -->人们遇到的最常见的错误之一是其代码只对玩家 0 有效，因为他们忘记初始化变量。如果没有玩家/物体/车辆 0，代码将不适用于任何人 - 没有人被提升为管理员比错误的人被提升为管理员要好。</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="-1"><code>-1</code><a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#-1" class="hash-link" aria-label="-1的直接链接" title="-1的直接链接" translate="no">​</a></h4>
<p>使用 <code>-1</code> 作为无效值有一些优点：</p>
<ul>
<li class="">它<strong>是</strong>一个无效索引。这不是 <code>0</code> 的一个优点，因为你的代码经常会继续运行而不是崩溃，但有了 crashdetect，这可能是一件好事 - 你的代码中有一个错误，崩溃会告诉你它在哪里，有时甚至精确到源代码行。是悄无声息地继续运行好，还是大声地结束运行好？</li>
<li class="">人们习惯于 <code>0</code> 在大多数情况下是一个有效值。程序员从 <code>0</code> 开始计数，所以它应该是有效的，而正整数范围之外的东西应该是无效的。</li>
<li class="">在无符号数学中，它是最大可能的整数 - <code>0xFFFFFFFF</code>，<code>4294967295</code>。这意味着任何实体类型的内在硬限制是其可能的最大值 - 在耗尽 ID（和内存）之前可以有 <code>4,294,967,295</code> 个物品。</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="针对玩家的函数-1">针对玩家的函数<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E9%92%88%E5%AF%B9%E7%8E%A9%E5%AE%B6%E7%9A%84%E5%87%BD%E6%95%B0-1" class="hash-link" aria-label="针对玩家的函数的直接链接" title="针对玩家的函数的直接链接" translate="no">​</a></h3>
<p>简而言之，这些已经不复存在。每个 <code>ForPlayer</code>、<code>ForAll</code>、<code>CreatePlayerX</code> 等函数都已被一个简单的函数取代 - <code>X_Display</code>（其中 <code>X</code> 是任何实体），以及用于检查的 <code>X_Has</code>：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">Object_Display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 显示它。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Object_Display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> false</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 隐藏它。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Text_Display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">textid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 向所有人显示它。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">Zone_Has</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">zoneid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 玩家**允许**看到这个帮派区域。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>YSI 使用 <code>X_SetPlayer</code>，但向玩家显示东西是最基本的事情，所以它值得拥有自己的动词。一些库使用 <code>X_Show</code> 和 <code>X_Hide</code>，但这是两个函数，当需要检查该做哪个时，只会导致代码冗余：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">var</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Checkpoint_Show</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cpid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Checkpoint_Hide</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cpid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>对比</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">Checkpoint_Display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cpid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> var</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>请注意，仅仅调用 <code>X_Display</code> 可能实际上并不会显示物品。世界另一端的物体仍然不可见。不同虚拟世界中的检查点，即使就在你旁边，也不会可见。对于世界实体，这只是表示玩家<strong>允许</strong>看到它，而不是他们当前<strong>能够</strong>看到它。相反，对于 HUD 元素，如菜单和对话框，这会立即显示它们，并且当只允许显示一个时，可能会隐藏其他的。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ids-1">IDs<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#ids-1" class="hash-link" aria-label="IDs的直接链接" title="IDs的直接链接" translate="no">​</a></h3>
<p>随着针对玩家池的移除和无效 ID 的统一，这不再是问题。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="更智能的函数">更智能的函数<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E6%9B%B4%E6%99%BA%E8%83%BD%E7%9A%84%E5%87%BD%E6%95%B0" class="hash-link" aria-label="更智能的�函数的直接链接" title="更智能的函数的直接链接" translate="no">​</a></h2>
<p>上面展示的 <code>X_Display</code> 函数可以接受两个参数 - 实体和显示状态，以便让每个玩家都能看到它们；或者也可以接受三个参数 - 实体、玩家和显示状态。还有其他函数也具有类似的智能参数处理。</p>
<p>一组例子是各种旋转函数。如介绍中所述，至少有四种不同的方法来获取和设置不同实体的旋转。现在只有一个 - <code>X_SetRotation</code> 和 <code>X_GetRotation</code>。</p>
<p>例如：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 只获取 `z`。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">z </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Player_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 x, y, 和 z 欧拉角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Object_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 w, x, y, 和 z 四元数角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Vehicle_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">vehicleid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>哪个用于哪个实体？全部都是：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 只获取 `z`。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">z </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Object_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 x, y, 和 z 欧拉角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Object_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 w, x, y, 和 z 四元数角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Object_GetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objectid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>参数和返回值的含义由给出的参数数量决定。</p>
<p>对于 Set 也是如此：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 只设置 `z`。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Vehicle_SetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">vehicleid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 设置 x, y, 和 z 欧拉角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Vehicle_SetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">vehicleid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 设置 w, x, y, 和 z 四元数角。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">Vehicle_SetRotation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">vehicleid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="结论">结论<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#%E7%BB%93%E8%AE%BA" class="hash-link" aria-label="结论的直接链接" title="结论的直接链接" translate="no">​</a></h2>
<p>我们非常努力地尝试创建一个易于使用、易于学习，同时也向后兼容的 API。SA<!-- -->:MP<!-- --> 的成功很大程度上源于其易用性，我们希望保持这一点，但也知道有高级用户希望从代码中获得更多功能。达成这种平衡总是很困难的，尤其是当发表评论最多的人往往是最有经验的人——那些精通这门语言并希望进一步推动它的人。这会导致一个系统为了高级功能而自我选择，牺牲了初学者的利益。我们不希望这样，但我们仍然希望听到你的想法。</p>
<p>你喜欢哪些语言和 API 功能，不喜欢哪些？哪些函数能帮助你最大限度地利用你的代码？你认为新设计是简单，还是太复杂？你能接受当前函数名杂乱无章吗？它们能达到目的，为什么要改变它们？作为初学者，你希望有什么不同的处理方式吗？</p>
<p>请在下面 burgershot 主题中分享你可能有的任何反馈。我们很乐意听取你的意见：</p>
<p><a href="https://forum.open.mp/showthread.php?tid=1036" target="_blank" rel="noopener noreferrer" class="">https://forum.open.mp/showthread.php?tid=1036</a></p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorTargetStickyNavbar_Vzrq sr-only" id="footnote-label">Footnotes<a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#footnote-label" class="hash-link" aria-label="Footnotes的直接链接" title="Footnotes的直接链接" translate="no">​</a></h2>
<ol>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-1-b0e7ce">
<p>有趣的旁注。得益于我们抽象脚本 API 代码的方式，Dialog_IsValid 的实现如下：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">SCRIPT_API</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Dialog_IsValid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">bool</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Dialog_s</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> true</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>就这些。实际上不需要任何实现，因为要调用这个函数，实体查找必须成功，因此我们可以立即返回 true。 <a href="https://omp.itsneufox.com/zh-CN/blog/scripting-api#user-content-fnref-1-b0e7ce" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[在 open.mp 中进行测试]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/debugging</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/debugging</guid>
            <pubDate>Mon, 06 Apr 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[在 SA:MP 中测试向来具有挑战性，但 open.mp 引入了新的工具，使其变得更加简单高效。借助开源代码库、增强的调试工具以及一个用于模拟玩家交互的强大新“mock”库，测试比以往任何时候都更自动化、更可靠。]]></description>
            <content:encoded><![CDATA[<p>在 SA<!-- -->:MP<!-- --> 中测试向来具有挑战性，但 open.mp 引入了新的工具，使其变得更加简单高效。借助开源代码库、增强的调试工具以及一个用于模拟玩家交互的强大新“mock”库，测试比以往任何时候都更自动化、更可靠。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>以下内容已过时，不反映 open.mp 的当前状态。本文发布于此仅作归档用。</p></div></div>
<p>在 SA<!-- -->:MP<!-- --> 中进行测试并不容易。大多数情况下，只是连接到服务器并在各处放置打印语句。像 y_testing 这样的库使编写单元测试变得容易得多，但仅限于相当“纯粹”的代码——即主要在服务器端运行，没有太多玩家交互的代码。你可以用这种方式测试大量令人惊讶的行为，但它仍然有限，并且在问题真正出现时，并不能帮助缩小范围。</p>
<p>那么 open.mp 是如何解决这个问题的呢？首先，代码是开源的，所以你可以使用所有现成的调试工具，例如 GDB 和 Visual Studio，来单步调试和检查代码。我们还计划为 Pawn 脚本本身添加类似的工具。</p>
<p>但最大的新特性是“mock”库。简而言之，它允许你创建假的玩家，这些玩家的行为与真实玩家完全相同，但没有任何客户端连接。因此，脚本对这些假玩家执行的任何操作都可以被另一个脚本读取和分析。让我们以一个最简单的例子来首次演示——向玩家显示一个检查点，并确认它已被发送。使用 y_testing 时，你执行操作后必须实际询问玩家是否看到了，这很慢，不可重复，而且很繁琐：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">PTEST__ </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASK</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"你看到世界中间有一个检查点吗？"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>使用像 “Pawn.RakNet” 这样的库可以通过自动检查传出数据包来消除询问，但仍然需要一个已连接的玩家，因此无法自动化和重复：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">static</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    gCheckpointPlayer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">gX</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">gY</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">gZ</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">gS</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">PTEST__ </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gX </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gY </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gZ </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gS </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gCheckpointPlayer </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">OPacket</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">107</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BitStream</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    gCheckpointPlayer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> playerid</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">BS_IgnoreBits</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">BS_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> gX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">BS_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> gY</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">BS_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> gZ</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">BS_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> gS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>在 open.mp 中，我们有一个类似于 Pawn.RakNet 的 API，但是用于模拟玩家。因此，你可以创建一个没有游戏实例的玩家，并像对待普通玩家一样使用它：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">TEST__ </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Mock_CreatePlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Mr Mock"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 清除所有现有数据包，便于搜索。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Mock_PurgeSent</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 正常显示一个检查点。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查是否看到了一个“SetCheckpoint”数据包。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new MockPacket</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">packet </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Mock_GetPacket</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"SetCheckpoint"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查数据包有4个组件，每个32位。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_Components</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_Bits</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查各个组件。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">tmp</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>这段代码完全可重复测试，是自包含的（没有全局变量和额外回调），并且易于扩展。</p>
<p>但有时情况并非如此简单。如果你创建一个物体，你不能仅仅检查它是否立即发送给了玩家，因为他们可能离它很远，因此内置的streamer尚未将其发送给他们。为了解决这个问题，我们首先需要稍微绕开一下，解释一下像 <code>SetPlayerPos</code> 这样的基本同步是如何工作的。当你使用 <code>SetPlayerPos</code> 设置玩家的位置时，服务器并不会立即在内部以及为所有其他玩家更新他们的位置。相反，一个 <code>SET POSITION</code> 命令被发送给那个正在被移动的玩家，他们被传送到新位置，然后在下一个同步数据包中将新位置报告回服务器。原因基本上是延迟——在设置新位置后，可能仍有一个或多个使用旧位置的同步数据包在传输中。那么这对于模拟玩家意味着什么呢？这意味着你实际上无法设置他们的位置，至少不能以正常方式设置。因为没有真正的客户端，所以没有东西接收数据包（即设置位置的命令），也没有东西将数据同步回服务器。</p>
<p>我们可以从模拟玩家为服务器生成任何模拟的同步数据，所以这是一种更新他们位置的方法，但对于一个常见操作来说可能有点繁琐，因此针对这个特定用例，有一个 <code>Mock_SetPlayerPos</code> 函数。但这还不是全部，因为我们需要streamer运行并根据他们的新位置进行更新，这只会周期性地发生（每隔几毫秒，取决于服务器滴答率）。为此，我们有另一个模拟函数——<code>Mock_Tick</code>，它可以将服务器时间瞬间向前跳转指定的微秒数（注意，不是毫秒）。这在真实服务器上绝对不应该使用，因为它会给定时器和其他对时间敏感的代码带来各种奇怪的问题，但可以用来在测试中模拟时间的流逝。请注意，<code>Mock_Tick(10000)</code> 不会延迟 10 毫秒，而是会将时间瞬间向前跳转 10 毫秒。</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">TEST__ </span><span class="token function" style="color:#d73a49">SetPlayerCheckpoint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Mock_CreatePlayer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Mr Mock"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 清除所有现有数据包，便于搜索。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Mock_PurgeSent</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 创建一个物体。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">CreateObject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1337</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 将模拟玩家的位置更新到服务器，使其靠近该物体。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Mock_SetPlayerPos</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">105.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">105.0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 现在模拟经过一段时间，以便streamer运行（50毫秒应该足够）。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Mock_Tick</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">50000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查是否看到了一个“CreateObject”数据包。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new MockPacket</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">packet </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Mock_GetPacket</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">playerid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"CreateObject"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查数据包是否有4个以上的组件，每个32位。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_Components</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 检查数据包的一些组件。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new </span><span class="token keyword" style="color:#00009f">int</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    new Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">tmp</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadInt32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">int</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">int</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1337</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">MockPacket_ReadFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tmp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">ASSERT</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tmp </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>关于 <code>Mock_Tick</code> 的一个重要说明。如果你调用它，比如 <code>Mock_Tick(100000)</code>，并且有一个 1 毫秒的定时器正在运行，这会立即使定时器触发，但定时器会认为它错过了很长时间（100毫秒）并会重新排队等待自己。在 <code>Mock_Tick</code> 调用期间，定时器会触发一次，但在当前测试结束后，由于定时器认为它错过了 100 次调用时间，它会被进一步排队 99 次，每次滴答一次。</p>
<p>以后我们会介绍一些更高级的调试技术，以便你可以更轻松地读写假的数据包，而不是像那段代码中那样一次一个组件，但这介绍了构建所有其他功能的基础。希望这能让每个人的代码开发和测试都变得更加容易（同时也能确保服务器更加稳定）。</p>
<p>明天我们还将深入探讨 open.mp 的 API 设计。它与 SA<!-- -->:MP<!-- --> 完全向后兼容，但这并不意味着没有并行的改进空间。</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[车辆同步]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/vehicle-sync</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/vehicle-sync</guid>
            <pubDate>Sat, 09 Nov 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[一篇简短的帖子展示了车辆同步技术的发展历程。]]></description>
            <content:encoded><![CDATA[<p>一篇简短的帖子展示了车辆同步技术的发展历程。</p>
<video autoplay="" loop="" width="100%" controls=""><source src="/zh-CN/assets/medias/vehicle_sync_01-115525d42cb827b58443f71baedf9b42.mp4" type="video/mp4"></video>
<video autoplay="" loop="" width="100%" controls=""><source src="/zh-CN/assets/medias/vehicle_sync_02-fe8141022639554363f8904dd1756227.mp4" type="video/mp4"></video>
<video autoplay="" loop="" width="100%" controls=""><source src="/zh-CN/assets/medias/vehicle_sync_03-34a6a71412eb7a6c7c9413023445bb04.mp4" type="video/mp4"></video>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Turf（原帮派区域）模块]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/turfs-formerly-gangzones-module</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/turfs-formerly-gangzones-module</guid>
            <pubDate>Sat, 19 Oct 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[大家好！我刚刚完成了Turf（领地）功能在服务器中的实现，觉得可以发文介绍一下这个模块，顺便告诉大家我们并没有放弃或停止开发！]]></description>
            <content:encoded><![CDATA[<p>大家好！我刚刚完成了Turf（领地）功能在服务器中的实现，觉得可以发文介绍一下这个模块，顺便告诉大家我们并没有放弃或停止开发！</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>以下内容已过时，不反映 open.mp 的当前状态。本文发布于此仅作归档用。</p></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 创建一个领地。可指定一个玩家ID将其设为该玩家的领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Turf_Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">minx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">miny</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">maxx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Float</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">maxy</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">owner </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> INVALID_PLAYER_ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 销毁一个领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Turf_Destroy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">turf</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 向一个或一批玩家显示一个领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 如果 playerid = INVALID_PLAYER_ID，将发送给所有玩家。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Turf_Show</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">turf</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> colour</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> INVALID_PLAYER_ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 对一个或一批玩家隐藏一个领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 如果 playerid = INVALID_PLAYER_ID，将发送给所有玩家。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Turf_Hide</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">turf</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> INVALID_PLAYER_ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 对一个或一批玩家闪烁显示一个领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 如果 playerid = INVALID_PLAYER_ID，将发送给所有玩家。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Turf_Flash</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">turf</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> colour</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> INVALID_PLAYER_ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 停止对一个或一批玩家闪烁显示一个领地。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 如果 playerid = INVALID_PLAYER_ID，将发送给所有玩家。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Turf_StopFlashing</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Turf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">turf</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Player</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">playerid </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> INVALID_PLAYER_ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>很明显，这与传统API不同，但不用担心，我们会为这类功能提供封装层，以确保普通脚本无需修改即可重新编译，且不会出现问题。</p>
<p>你可能还想知道另一个重要事实：所有Turf都在同一个资源池中，脚本最多可以创建4,294,967,295个Turf。但是，客户端一次最多只能同时处理1024个Turf。</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[定时器模块]]></title>
            <link>https://omp.itsneufox.com/zh-CN/blog/timers</link>
            <guid>https://omp.itsneufox.com/zh-CN/blog/timers</guid>
            <pubDate>Wed, 22 May 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[本篇前瞻文章展示了 open.mp 中定时器模块的改进，在保持向后兼容的同时，引入了一个更灵活、高效的 API。]]></description>
            <content:encoded><![CDATA[<p>本篇前瞻文章展示了 open.mp 中定时器模块的改进，在保持向后兼容的同时，引入了一个更灵活、高效的 API。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>以下内容已过时，不反映 open.mp 的当前状态。本文发布于此仅作归档用。</p></div></div>
<p>这是我们对 open.mp 中定时器模块所做改进的一次前瞻性展示：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">SetTimer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> func</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> msInterval</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> bool</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">repeat</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> SetTimerEx</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">SetTimerEx</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> func</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> msInterval</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> bool</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">repeat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> params</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GLOBAL_TAG_TYPES</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">KillTimer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Timer_Kill</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 创建定时器</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Timer_Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> func</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> usDelay</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> usInterval</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> repeatCount</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> params</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GLOBAL_TAG_TYPES</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 终止定时器</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Timer_Kill</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 返回下一次调用前的剩余时间。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Timer_GetTimeRemaining</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取剩余调用次数（0 表示无限）。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Timer_GetCallsRemaining</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 `repeatCount` 参数。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Timer_GetTotalCalls</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 获取 `usInterval` 参数。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native </span><span class="token function" style="color:#d73a49">Timer_GetInterval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 将距离下次调用的剩余时间重置为 `usInterval`。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">native bool</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Timer_Restart</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>前两个函数仅用于向后兼容，其余的是改进后的 API：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">native Timer</span><span class="token operator" style="color:#393A34">:</span><span class="token function" style="color:#d73a49">Timer_Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> func</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> usDelay</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> usInterval</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> repeatCount</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> params</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GLOBAL_TAG_TYPES</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<ul>
<li class=""><code>func</code> - 作用显而易见，即指定要调用的函数。</li>
<li class=""><code>usDelay</code> - 同样显而易见，表示首次调用前的延迟时间（以微秒计）。</li>
<li class=""><code>usInterval</code> - 指定第一次调用后，将 usDelay 重置为何值。例如，如果你希望每小时执行一次定时器，而现在是上午 8:47，调用方式应为 <code>Timer_Create("OnTheHour", 780 SECONDS, 3600 SECONDS, 0);</code></li>
<li class=""><code>repeatCount</code> - 与旧函数仅支持"一次"或"永久"不同，此参数指定调用函数的次数。"一次"为 <code>1</code>，<code>500</code> 表示调用 500 次后停止，（与旧 API 相反）<code>0</code> 表示"永久执行"。</li>
<li class=""><code>GLOBAL_TAG_TYPES</code> - 类似于 <code>{Float, ...}</code>，但支持更多标签。</li>
</ul>]]></content:encoded>
        </item>
    </channel>
</rss>